using System.Net; using System.Net.Http.Json; using FluentAssertions; using RacePlannerApi.DTOs; using RacePlannerApi.Models; using Xunit; namespace backend.Tests.Integration; public class EventsIntegrationTests : IntegrationTestBase { public EventsIntegrationTests(WebApplicationFactory factory) : base(factory) { } private async Task GetOrganizerTokenAsync() { // Register and login as organizer var registerRequest = new RegisterRequest { Email = "organizer@test.com", Password = "SecurePass123!", Name = "Test Organizer", Role = UserRole.Organizer }; await _client.PostAsJsonAsync("/api/auth/register", registerRequest); var loginRequest = new LoginRequest { Email = "organizer@test.com", Password = "SecurePass123!" }; var loginResponse = await _client.PostAsJsonAsync("/api/auth/login", loginRequest); var authResult = await loginResponse.Content.ReadFromJsonAsync(); return authResult!.Token; } [Fact] public async Task GetEvents_ReturnsPublishedEvents() { // Act var response = await _client.GetAsync("/api/events"); // Assert response.StatusCode.Should().Be(HttpStatusCode.OK); var events = await response.Content.ReadFromJsonAsync>(); events.Should().NotBeNull(); } [Fact] public async Task CreateEvent_WithValidData_ReturnsCreated() { // Arrange var token = await GetOrganizerTokenAsync(); var client = CreateAuthenticatedClient(token); var request = new CreateEventRequest { Name = "Test Marathon", Description = "A test marathon event", EventDate = DateTime.UtcNow.AddDays(30), Location = "Test City", Category = "Running", Tags = new List(), MaxParticipants = 100 }; // Act var response = await client.PostAsJsonAsync("/api/events", request); // Assert response.StatusCode.Should().Be(HttpStatusCode.Created); var result = await response.Content.ReadFromJsonAsync(); result.Should().NotBeNull(); result!.Name.Should().Be(request.Name); result.Status.Should().Be("Draft"); } [Fact] public async Task CreateEvent_WithoutAuth_ReturnsUnauthorized() { // Arrange var request = new CreateEventRequest { Name = "Test Event", EventDate = DateTime.UtcNow.AddDays(30), Location = "Test City" }; // Act var response = await _client.PostAsJsonAsync("/api/events", request); // Assert response.StatusCode.Should().Be(HttpStatusCode.Unauthorized); } [Fact] public async Task GetEvent_WithValidId_ReturnsEvent() { // Arrange - Create an event first var token = await GetOrganizerTokenAsync(); var client = CreateAuthenticatedClient(token); var createRequest = new CreateEventRequest { Name = "Test Event", Description = "Test description", EventDate = DateTime.UtcNow.AddDays(30), Location = "Test City", Category = "Running", Tags = new List(), MaxParticipants = 50 }; var createResponse = await client.PostAsJsonAsync("/api/events", createRequest); var createdEvent = await createResponse.Content.ReadFromJsonAsync(); // Publish the event so it's visible var updateRequest = new UpdateEventRequest { Status = EventStatus.Published }; await client.PutAsJsonAsync($"/api/events/{createdEvent!.Id}", updateRequest); // Act - Get the event as anonymous user var getResponse = await _client.GetAsync($"/api/events/{createdEvent.Id}"); // Assert getResponse.StatusCode.Should().Be(HttpStatusCode.OK); var result = await getResponse.Content.ReadFromJsonAsync(); result.Should().NotBeNull(); result!.Id.Should().Be(createdEvent.Id); } [Fact] public async Task GetEvent_WithInvalidId_ReturnsNotFound() { // Act var response = await _client.GetAsync($"/api/events/{Guid.NewGuid()}"); // Assert response.StatusCode.Should().Be(HttpStatusCode.NotFound); } [Fact] public async Task UpdateEvent_WithValidData_ReturnsUpdatedEvent() { // Arrange var token = await GetOrganizerTokenAsync(); var client = CreateAuthenticatedClient(token); var createRequest = new CreateEventRequest { Name = "Original Name", EventDate = DateTime.UtcNow.AddDays(30), Location = "Original Location", Category = "Running", Tags = new List(), MaxParticipants = 50 }; var createResponse = await client.PostAsJsonAsync("/api/events", createRequest); var createdEvent = await createResponse.Content.ReadFromJsonAsync(); var updateRequest = new UpdateEventRequest { Name = "Updated Name", Description = "Updated description" }; // Act var response = await client.PutAsJsonAsync($"/api/events/{createdEvent!.Id}", updateRequest); // Assert response.StatusCode.Should().Be(HttpStatusCode.OK); var result = await response.Content.ReadFromJsonAsync(); result.Should().NotBeNull(); result!.Name.Should().Be("Updated Name"); result.Description.Should().Be("Updated description"); } [Fact] public async Task DeleteEvent_AsOrganizer_ReturnsNoContent() { // Arrange var token = await GetOrganizerTokenAsync(); var client = CreateAuthenticatedClient(token); var createRequest = new CreateEventRequest { Name = "Event to Delete", EventDate = DateTime.UtcNow.AddDays(30), Location = "Test City", Category = "Running", Tags = new List(), MaxParticipants = 50 }; var createResponse = await client.PostAsJsonAsync("/api/events", createRequest); var createdEvent = await createResponse.Content.ReadFromJsonAsync(); // Act var response = await client.DeleteAsync($"/api/events/{createdEvent!.Id}"); // Assert response.StatusCode.Should().Be(HttpStatusCode.NoContent); // Verify event is deleted var getResponse = await client.GetAsync($"/api/events/{createdEvent.Id}"); getResponse.StatusCode.Should().Be(HttpStatusCode.NotFound); } }