Skip to content
Merged
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
31 changes: 27 additions & 4 deletions TickAPI/TickAPI.Tests/Events/Controllers/EventControllerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using TickAPI.Addresses.DTOs.Request;
using TickAPI.Categories.DTOs.Request;
using TickAPI.Common.Claims.Abstractions;
using TickAPI.Common.Pagination.Responses;
using TickAPI.Events.Controllers;
Expand All @@ -13,6 +14,7 @@
using TickAPI.Events.DTOs.Response;
using TickAPI.Organizers.Abstractions;
using TickAPI.Organizers.Models;
using TickAPI.TicketTypes.DTOs.Request;

namespace TickAPI.Tests.Events.Controllers;

Expand All @@ -30,12 +32,22 @@ public async Task CreateEvent_WhenDataIsValid_ShouldReturnSuccess()
const string email = "123@mail.com";
const EventStatus eventStatus = EventStatus.TicketsAvailable;
Guid id = Guid.NewGuid();
List<CreateEventCategoryDto> categories =
[
new CreateEventCategoryDto("concert"),
new CreateEventCategoryDto("bear metal")
];
List<CreateEventTicketTypeDto> ticketTypes =
[
new CreateEventTicketTypeDto("normal", 100, 50.9m, "zł", new DateTime(2025, 5, 1)),
new CreateEventTicketTypeDto("V.I.P", 10, 500.9m, "zł", new DateTime(2025, 5, 10)),
];
CreateAddressDto createAddress = new CreateAddressDto("United States", "New York", "Main st", 20, null, "00-000");
CreateEventDto eventDto = new CreateEventDto(name, description, startDate, endDate, minimumAge, eventStatus, createAddress);
CreateEventDto eventDto = new CreateEventDto(name, description, startDate, endDate, minimumAge, categories, ticketTypes, eventStatus, createAddress);

var eventServiceMock = new Mock<IEventService>();
eventServiceMock
.Setup(m => m.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, eventStatus, email))
.Setup(m => m.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, categories , ticketTypes, eventStatus, email))
.ReturnsAsync(Result<Event>.Success(new Event()));

var claims = new List<Claim>
Expand Down Expand Up @@ -79,6 +91,17 @@ public async Task CreateEvent_WhenMissingEmailClaims_ShouldReturnBadRequest()
DateTime endDate = new DateTime(2025, 6, 1);
uint? minimumAge = 18;
const EventStatus eventStatus = EventStatus.TicketsAvailable;
string email = "123@mail.com";
List<CreateEventCategoryDto> categories =
[
new CreateEventCategoryDto("concert"),
new CreateEventCategoryDto("bear metal")
];
List<CreateEventTicketTypeDto> ticketTypes =
[
new CreateEventTicketTypeDto("normal", 100, 50.9m, "zł", new DateTime(2025, 5, 1)),
new CreateEventTicketTypeDto("V.I.P", 10, 500.9m, "zł", new DateTime(2025, 5, 10)),
];
CreateAddressDto createAddress = new CreateAddressDto("United States", "New York", "Main st", 20, null, "00-000");

var eventServiceMock = new Mock<IEventService>();
Expand All @@ -97,8 +120,8 @@ public async Task CreateEvent_WhenMissingEmailClaims_ShouldReturnBadRequest()
}
};

// Act
var res = await sut.CreateEvent(new CreateEventDto(name, description, startDate, endDate, minimumAge, eventStatus, createAddress));
// act
var res = await sut.CreateEvent(new CreateEventDto(name, description, startDate, endDate, minimumAge, categories, ticketTypes, eventStatus, createAddress));

// Assert
var result = Assert.IsType<ActionResult<CreateEventResponseDto>>(res);
Expand Down
181 changes: 164 additions & 17 deletions TickAPI/TickAPI.Tests/Events/Services/EventServiceTests.cs

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions TickAPI/TickAPI/Categories/Abstractions/ICategoryService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ public interface ICategoryService
public Task<Result<Category>> GetCategoryByNameAsync(string categoryName);
public Task<Result<PaginatedData<GetCategoryResponseDto>>> GetCategoriesResponsesAsync(int pageSize, int page);
public Task<Result<Category>> CreateNewCategoryAsync(string categoryName);

public Task<bool> CheckIfCategoriesExistAsync(IEnumerable<Category> categories);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace TickAPI.Categories.DTOs.Request;

public record CreateEventCategoryDto
(
string CategoryName
);
10 changes: 9 additions & 1 deletion TickAPI/TickAPI/Categories/Services/CategoryService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using TickAPI.Categories.Abstractions;
using Microsoft.EntityFrameworkCore;
using TickAPI.Categories.Abstractions;
using TickAPI.Categories.DTOs.Response;
using TickAPI.Categories.Models;
using TickAPI.Common.Pagination.Abstractions;
Expand Down Expand Up @@ -55,4 +56,11 @@ public async Task<Result<Category>> CreateNewCategoryAsync(string categoryName)
await _categoryRepository.AddNewCategoryAsync(category);
return Result<Category>.Success(category);
}

public async Task<bool> CheckIfCategoriesExistAsync(IEnumerable<Category> categories)
{
var dbCategories = _categoryRepository.GetCategories();
int count = await dbCategories.Where(cdb => categories.Any(c => c.Name == cdb.Name)).CountAsync();
return count == categories.Count();
}
}
5 changes: 4 additions & 1 deletion TickAPI/TickAPI/Events/Abstractions/IEventService.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
using TickAPI.Addresses.DTOs.Request;
using TickAPI.Common.Pagination.Responses;
using TickAPI.Categories.DTOs.Request;
using TickAPI.Events.Models;
using TickAPI.Common.Results.Generic;
using TickAPI.Events.DTOs.Response;
using TickAPI.Organizers.Models;
using TickAPI.TicketTypes.DTOs.Request;

namespace TickAPI.Events.Abstractions;

public interface IEventService
{
public Task<Result<Event>> CreateNewEventAsync(string name, string description, DateTime startDate,
DateTime endDate, uint? minimumAge, CreateAddressDto createAddress, EventStatus eventStatus, string organizerEmail);
DateTime endDate, uint? minimumAge, CreateAddressDto createAddress, List<CreateEventCategoryDto> categories
, List<CreateEventTicketTypeDto> ticketTypes,EventStatus eventStatus, string organizerEmail);
public Task<Result<PaginatedData<GetEventResponseDto>>> GetOrganizerEventsAsync(Organizer organizer, int page, int pageSize);
public Task<Result<PaginationDetails>> GetOrganizerEventsPaginationDetailsAsync(Organizer organizer, int pageSize);
public Task<Result<PaginatedData<GetEventResponseDto>>> GetEventsAsync(int page, int pageSize);
Expand Down
4 changes: 3 additions & 1 deletion TickAPI/TickAPI/Events/Controllers/EventController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ public async Task<ActionResult<CreateEventResponseDto>> CreateEvent([FromBody] C
}
var email = emailResult.Value!;

var newEventResult = await _eventService.CreateNewEventAsync(request.Name, request.Description, request.StartDate, request.EndDate, request.MinimumAge, request.CreateAddress, request.EventStatus, email);
var newEventResult = await _eventService.CreateNewEventAsync(request.Name, request.Description,
request.StartDate, request.EndDate, request.MinimumAge, request.CreateAddress, request.Categories
, request.TicketTypes ,request.EventStatus, email);

if (newEventResult.IsError)
return StatusCode(newEventResult.StatusCode, newEventResult.ErrorMsg);
Expand Down
7 changes: 5 additions & 2 deletions TickAPI/TickAPI/Events/DTOs/Request/CreateEventDto.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
using TickAPI.Events.Models;
using TickAPI.Addresses.DTOs.Request;
using TickAPI.Categories.DTOs.Request;
using TickAPI.TicketTypes.DTOs.Request;

namespace TickAPI.Events.DTOs.Request;

public record CreateEventDto
(
public record CreateEventDto(
string Name,
string Description,
DateTime StartDate,
DateTime EndDate,
uint? MinimumAge,
List<CreateEventCategoryDto> Categories,
List<CreateEventTicketTypeDto> TicketTypes,
EventStatus EventStatus,
CreateAddressDto CreateAddress
);
45 changes: 39 additions & 6 deletions TickAPI/TickAPI/Events/Services/EventService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@
using TickAPI.Addresses.DTOs.Request;
using TickAPI.Common.Pagination.Abstractions;
using TickAPI.Common.Pagination.Responses;
using TickAPI.Categories.Abstractions;
using TickAPI.Categories.DTOs.Request;
using TickAPI.Categories.Models;
using TickAPI.Common.Time.Abstractions;
using TickAPI.Events.Abstractions;
using TickAPI.Events.Models;
using TickAPI.Common.Results.Generic;
using TickAPI.Events.DTOs.Response;
using TickAPI.Organizers.Abstractions;
using TickAPI.Organizers.Models;
using TickAPI.TicketTypes.DTOs.Request;
using TickAPI.TicketTypes.Models;

namespace TickAPI.Events.Services;

Expand All @@ -19,17 +24,21 @@ public class EventService : IEventService
private readonly IAddressService _addressService;
private readonly IDateTimeService _dateTimeService;
private readonly IPaginationService _paginationService;
private readonly ICategoryService _categoryService;

public EventService(IEventRepository eventRepository, IOrganizerService organizerService, IAddressService addressService, IDateTimeService dateTimeService, IPaginationService paginationService)
public EventService(IEventRepository eventRepository, IOrganizerService organizerService, IAddressService addressService, IDateTimeService dateTimeService, IPaginationService paginationService, ICategoryService categoryService)
{
_eventRepository = eventRepository;
_organizerService = organizerService;
_addressService = addressService;
_dateTimeService = dateTimeService;
_paginationService = paginationService;
_categoryService = categoryService;
}

public async Task<Result<Event>> CreateNewEventAsync(string name, string description, DateTime startDate, DateTime endDate, uint? minimumAge, CreateAddressDto createAddress, EventStatus eventStatus, string organizerEmail)
public async Task<Result<Event>> CreateNewEventAsync(string name, string description, DateTime startDate, DateTime endDate,
uint? minimumAge, CreateAddressDto createAddress, List<CreateEventCategoryDto> categories, List<CreateEventTicketTypeDto> ticketTypes,
EventStatus eventStatus, string organizerEmail)
{
var organizerResult = await _organizerService.GetOrganizerByEmailAsync(organizerEmail);
if (!organizerResult.IsSuccess)
Expand All @@ -41,10 +50,32 @@ public async Task<Result<Event>> CreateNewEventAsync(string name, string descri

if (startDate < _dateTimeService.GetCurrentDateTime())
return Result<Event>.Failure(StatusCodes.Status400BadRequest, "Start date is in the past");


if (ticketTypes.Any(t => t.AvailableFrom > endDate))
{
return Result<Event>.Failure(StatusCodes.Status400BadRequest, "Tickets can't be available after the event is over");
}

var address = await _addressService.GetOrCreateAddressAsync(createAddress);


var categoriesConverted = categories.Select(c => new Category { Name = c.CategoryName }).ToList();

var categoriesExist = await _categoryService.CheckIfCategoriesExistAsync(categoriesConverted);
if (!categoriesExist)
{
return Result<Event>.Failure(StatusCodes.Status400BadRequest, "Category does not exist");
}

var ticketTypesConverted = ticketTypes.Select(t => new TicketType
{
Description = t.Description,
AvailableFrom = t.AvailableFrom,
Currency = t.Currency,
MaxCount = t.MaxCount,
Price = t.Price,
})
.ToList();

var @event = new Event
{
Name = name,
Expand All @@ -53,8 +84,10 @@ public async Task<Result<Event>> CreateNewEventAsync(string name, string descri
EndDate = endDate,
MinimumAge = minimumAge,
Address = address.Value!,
Categories = categoriesConverted,
Organizer = organizerResult.Value!,
EventStatus = eventStatus
EventStatus = eventStatus,
TicketTypes = ticketTypesConverted,
};
await _eventRepository.AddNewEventAsync(@event);
return Result<Event>.Success(@event);
Expand Down Expand Up @@ -99,7 +132,7 @@ private async Task<Result<PaginatedData<GetEventResponseDto>>> GetPaginatedEvent

private static GetEventResponseDto MapEventToGetEventResponseDto(Event ev)
{
var categories = ev.Categories.Select((c) => new GetEventResponseCategoryDto(c.Name)).ToList();
var categories = ev.Categories.Count > 0 ? ev.Categories.Select((c) => new GetEventResponseCategoryDto(c.Name)).ToList() : new List<GetEventResponseCategoryDto>();
var address = new GetEventResponseAddressDto(ev.Address.Country, ev.Address.City, ev.Address.PostalCode, ev.Address.Street, ev.Address.HouseNumber, ev.Address.FlatNumber);
return new GetEventResponseDto(ev.Name, ev.Description, ev.StartDate, ev.EndDate, ev.MinimumAge, categories, ev.EventStatus, address);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace TickAPI.TicketTypes.DTOs.Request;

public record CreateEventTicketTypeDto(
string Description,
uint MaxCount,
decimal Price,
string Currency,
DateTime AvailableFrom
);
Loading