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
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ public async Task CreateEvent_WhenDataIsValid_ShouldReturnSuccess()
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, categories, ticketTypes, eventStatus, createAddress);
CreateEventDto eventDto = new CreateEventDto(name, description, startDate, endDate, minimumAge, categories, ticketTypes, eventStatus, createAddress, null);

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

var claims = new List<Claim>
Expand Down Expand Up @@ -123,7 +123,7 @@ public async Task CreateEvent_WhenMissingEmailClaims_ShouldReturnBadRequest()
};

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

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

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions TickAPI/TickAPI.Tests/Events/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ public static GetEventResponseDto CreateSampleEventResponseDto(string name)
new GetEventResponsePriceInfoDto(300, "PLN"),
[new GetEventResponseCategoryDto("Test")],
EventStatus.TicketsAvailable,
new GetEventResponseAddressDto("United States", "New York", "10001", "Main St", 123, null)
new GetEventResponseAddressDto("United States", "New York", "10001", "Main St", 123, null),
null
);
}

Expand All @@ -69,7 +70,8 @@ [new GetEventResponseCategoryDto("Test")],
new GetEventDetailsResponseTicketTypeDto(Guid.Parse("7ecfc61a-32d2-4124-a95c-cb5834a49990"), "Description #2", 300, "PLN", new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), 30),
new GetEventDetailsResponseTicketTypeDto(Guid.Parse("7be2ae57-2394-4854-bf11-9567ce7e0ab6"), "Description #3", 200, "PLN", new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), 20)],
EventStatus.TicketsAvailable,
new GetEventResponseAddressDto("United States", "New York", "10001", "Main St", 123, null)
new GetEventResponseAddressDto("United States", "New York", "10001", "Main St", 123, null),
null
);
}
}
6 changes: 6 additions & 0 deletions TickAPI/TickAPI/Common/Blob/Abstractions/IBlobService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace TickAPI.Common.Blob.Abstractions;

public interface IBlobService
{
public Task<string> UploadToBlobContainerAsync(IFormFile image);
}
32 changes: 32 additions & 0 deletions TickAPI/TickAPI/Common/Blob/Services/BlobService.cs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a general question here, shouldn't we do some try/catch here? I mean for example blob can be down, what then? I guess the event should be created anyway, just without image - now what happens is that the exception will be propagated to main and the event will not be created. I guess we can simply do all of this in a try block, and if anything breaks just return null

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using Azure.Identity;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using TickAPI.Common.Blob.Abstractions;

namespace TickAPI.Common.Blob.Services;

public class BlobService : IBlobService
{
private string _connectionString;
private string _containerName;

public BlobService(IConfiguration configuration)
{
_connectionString = configuration["BlobStorage:ConnectionString"];
_containerName = configuration["BlobStorage:ContainerName"];
}

public async Task<string> UploadToBlobContainerAsync(IFormFile image)
{
var container = new BlobContainerClient(_connectionString, _containerName);
Guid id = Guid.NewGuid();
string blobName = id.ToString();
var blob = container.GetBlobClient(blobName);
var stream = new MemoryStream();
await image.CopyToAsync(stream);
stream.Position = 0;
var response = await blob.UploadAsync(stream);

return blob.Uri.ToString();
}
}
2 changes: 1 addition & 1 deletion TickAPI/TickAPI/Events/Abstractions/IEventService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public interface IEventService
{
public 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);
List<CreateEventTicketTypeDto> ticketTypes,EventStatus eventStatus, string organizerEmail, IFormFile? images);
public Task<Result<PaginatedData<GetEventResponseDto>>> GetOrganizerEventsAsync(Organizer organizer, int page, int pageSize, EventFiltersDto? eventFilters = null);
public Task<Result<PaginationDetails>> GetOrganizerEventsPaginationDetailsAsync(Organizer organizer, int pageSize);
public Task<Result<PaginatedData<GetEventResponseDto>>> GetEventsAsync(int page, int pageSize, EventFiltersDto? eventFilters = null);
Expand Down
4 changes: 2 additions & 2 deletions TickAPI/TickAPI/Events/Controllers/EventsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public EventsController(IEventService eventService, IClaimsService claimsService

[AuthorizeWithPolicy(AuthPolicies.VerifiedOrganizerPolicy)]
[HttpPost]
public async Task<ActionResult<CreateEventResponseDto>> CreateEvent([FromBody] CreateEventDto request)
public async Task<ActionResult<CreateEventResponseDto>> CreateEvent([FromForm] CreateEventDto request)
{
var emailResult = _claimsService.GetEmailFromClaims(User.Claims);
if (emailResult.IsError)
Expand All @@ -39,7 +39,7 @@ public async Task<ActionResult<CreateEventResponseDto>> CreateEvent([FromBody] C

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

if (newEventResult.IsError)
return newEventResult.ToObjectResult();
Expand Down
3 changes: 2 additions & 1 deletion TickAPI/TickAPI/Events/DTOs/Request/CreateEventDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ public record CreateEventDto(
List<CreateEventCategoryDto> Categories,
List<CreateEventTicketTypeDto> TicketTypes,
EventStatus EventStatus,
CreateAddressDto CreateAddress
CreateAddressDto CreateAddress,
IFormFile? Image
);
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ public record GetEventDetailsResponseDto(
List<GetEventResponseCategoryDto> Categories,
List<GetEventDetailsResponseTicketTypeDto> TicketTypes,
EventStatus Status,
GetEventResponseAddressDto Address
GetEventResponseAddressDto Address,
string? ImageUrl
);
3 changes: 2 additions & 1 deletion TickAPI/TickAPI/Events/DTOs/Response/GetEventResponseDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ public record GetEventResponseDto(
GetEventResponsePriceInfoDto MaximumPrice,
List<GetEventResponseCategoryDto> Categories,
EventStatus Status,
GetEventResponseAddressDto Address
GetEventResponseAddressDto Address,
string? ImageUrl
);
1 change: 1 addition & 0 deletions TickAPI/TickAPI/Events/Models/Event.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class Event
public ICollection<TicketType> TicketTypes { get; set; }
public EventStatus EventStatus { get; set; }
public Address Address { get; set; }
public string? ImageUrl { get; set; }
}

public enum EventStatus
Expand Down
27 changes: 22 additions & 5 deletions TickAPI/TickAPI/Events/Services/EventService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
using TickAPI.Tickets.Abstractions;
using TickAPI.TicketTypes.DTOs.Request;
using TickAPI.TicketTypes.Models;
using TickAPI.Common.Blob.Abstractions;

namespace TickAPI.Events.Services;

Expand All @@ -35,8 +36,9 @@ public class EventService : IEventService
private readonly ITicketService _ticketService;
private readonly ICustomerRepository _customerRepository;
private readonly IMailService _mailService;
private readonly IBlobService _blobService;

public EventService(IEventRepository eventRepository, IOrganizerService organizerService, IAddressService addressService, IDateTimeService dateTimeService, IPaginationService paginationService, ICategoryService categoryService, ITicketService ticketService, ICustomerRepository customerRepository, IMailService mailService)
public EventService(IEventRepository eventRepository, IOrganizerService organizerService, IAddressService addressService, IDateTimeService dateTimeService, IPaginationService paginationService, ICategoryService categoryService, ITicketService ticketService, ICustomerRepository customerRepository, IMailService mailService, IBlobService blobService)
{
_eventRepository = eventRepository;
_organizerService = organizerService;
Expand All @@ -47,11 +49,12 @@ public EventService(IEventRepository eventRepository, IOrganizerService organize
_ticketService = ticketService;
_customerRepository = customerRepository;
_mailService = mailService;
_blobService = blobService;
}

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)
EventStatus eventStatus, string organizerEmail, IFormFile? image)
{
var organizerResult = await _organizerService.GetOrganizerByEmailAsync(organizerEmail);
if (!organizerResult.IsSuccess)
Expand Down Expand Up @@ -82,7 +85,19 @@ public async Task<Result<Event>> CreateNewEventAsync(string name, string descri
{
return Result<Event>.PropagateError(categoriesByNameResult);
}


string? imageUrl = null;
if (image != null)
{
try
{
imageUrl = await _blobService.UploadToBlobContainerAsync(image);
}
catch (Exception e)
{
return Result<Event>.Failure(statusCode:500, e.Message);
}
}
var @event = new Event
{
Name = name,
Expand All @@ -95,6 +110,7 @@ public async Task<Result<Event>> CreateNewEventAsync(string name, string descri
Organizer = organizerResult.Value!,
EventStatus = eventStatus,
TicketTypes = ticketTypesConverted,
ImageUrl = imageUrl
};
await _eventRepository.AddNewEventAsync(@event);
return Result<Event>.Success(@event);
Expand Down Expand Up @@ -178,7 +194,8 @@ public async Task<Result<GetEventDetailsResponseDto>> GetEventDetailsAsync(Guid
categories,
ticketTypes,
ev.EventStatus,
address
address,
ev.ImageUrl
);

return Result<GetEventDetailsResponseDto>.Success(details);
Expand Down Expand Up @@ -309,7 +326,7 @@ private static GetEventResponseDto MapEventToGetEventResponseDto(Event ev)
var maximumPrice = new GetEventResponsePriceInfoDto(ttMaximumPrice.Price, ttMaximumPrice.Currency);

return new GetEventResponseDto(ev.Id, ev.Name, ev.Description, ev.StartDate, ev.EndDate, ev.MinimumAge,
minimumPrice, maximumPrice, categories, ev.EventStatus, address);
minimumPrice, maximumPrice, categories, ev.EventStatus, address, ev.ImageUrl);
}

private Result CheckEventDates(DateTime startDate, DateTime endDate, IEnumerable<TicketType> ticketTypes, bool skipStartDateEvaluation = false)
Expand Down
Loading
Loading