From 2d440eb9609505786e158454239543b824215f3f Mon Sep 17 00:00:00 2001 From: kTrzcinskii Date: Thu, 10 Apr 2025 18:16:02 +0200 Subject: [PATCH 01/33] Create `EventFilter` service --- .../Events/Services/EventFilterTests.cs | 171 ++++++++++++++++++ .../Events/Abstractions/IEventFilter.cs | 16 ++ .../TickAPI/Events/Services/EventFilter.cs | 49 +++++ TickAPI/TickAPI/Program.cs | 1 + 4 files changed, 237 insertions(+) create mode 100644 TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs create mode 100644 TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs create mode 100644 TickAPI/TickAPI/Events/Services/EventFilter.cs diff --git a/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs b/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs new file mode 100644 index 0000000..4e2735d --- /dev/null +++ b/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs @@ -0,0 +1,171 @@ +using TickAPI.Events.Models; +using TickAPI.Events.Services; +using TickAPI.TicketTypes.Models; + +namespace TickAPI.Tests.Events.Services; + +public class EventFilterTests +{ + private readonly EventFilter _eventFilter = new EventFilter(); + + private static List GetTestEvents() => + [ + new Event + { + Name = "Concert A", + Description = "An amazing rock concert", + StartDate = new DateTime(2025, 5, 1, 18, 0, 0), + EndDate = new DateTime(2025, 5, 1, 22, 0, 0), + MinimumAge = 18, + TicketTypes = new List + { + new TicketType { Price = 100 }, + new TicketType { Price = 120 } + } + }, + + new Event + { + Name = "Concert B", + Description = "Chill jazz night", + StartDate = new DateTime(2025, 6, 1), + EndDate = new DateTime(2025, 6, 2), + MinimumAge = 12, + TicketTypes = new List + { + new TicketType { Price = 50 } + } + }, + + new Event + { + Name = "Conference", + Description = "Tech event for developers", + StartDate = new DateTime(2025, 5, 1), + EndDate = new DateTime(2025, 5, 3), + MinimumAge = 21, + TicketTypes = new List + { + new TicketType { Price = 200 }, + new TicketType { Price = 150 } + } + } + ]; + + [Fact] + public void FilterByName_ShouldReturnMatchingEvents() + { + // Arrange + var events = GetTestEvents(); + + // Act + var result = _eventFilter.FilterByName(events.AsQueryable(), "concert").ToList(); + + // Assert + Assert.Equal(2, result.Count); + Assert.Contains(events[0], result); + Assert.Contains(events[1], result); + } + + [Fact] + public void FilterByDescription_ShouldReturnMatchingEvents() + { + // Arrange + var events = GetTestEvents(); + + // Act + var result = _eventFilter.FilterByDescription(events.AsQueryable(), "tech").ToList(); + + // Assert + Assert.Single(result); + Assert.Contains(events[2], result); + } + + [Fact] + public void FilterByStartDate_ShouldReturnMatchingEvents() + { + // Arrange + var events = GetTestEvents(); + + // Act + var result = _eventFilter.FilterByStartDate(events.AsQueryable(), new DateTime(2025, 5, 1)).ToList(); + + // Assert + Assert.Equal(2, result.Count); + Assert.Contains(events[0], result); + Assert.Contains(events[2], result); + } + + [Fact] + public void FilterByEndDate_ShouldReturnMatchingEvents() + { + // Arrange + var events = GetTestEvents(); + + // Act + var result = _eventFilter.FilterByEndDate(events.AsQueryable(), new DateTime(2025, 5, 1, 22, 0, 0)).ToList(); + + // Assert + Assert.Single(result); + Assert.Contains(events[0], result); + } + + [Fact] + public void FilterByMinPrice_ShouldReturnMatchingEvents() + { + // Arrange + var events = GetTestEvents(); + + // Act + var result = _eventFilter.FilterByMinPrice(events.AsQueryable(), 100).ToList(); + + // Assert + Assert.Equal(2, result.Count); + Assert.Contains(events[0], result); + Assert.Contains(events[2], result); + } + + [Fact] + public void FilterByMaxPrice_ShouldReturnMatchingEvents() + { + // Arrange + var events = GetTestEvents(); + + // Act + var result = _eventFilter.FilterByMaxPrice(events.AsQueryable(), 100).ToList(); + + // Assert + Assert.Single(result); + Assert.Contains(events[1], result); + } + + [Fact] + public void FilterByMinAge_ShouldReturnMatchingEvents() + { + // Arrange + var events = GetTestEvents(); + + // Act + var result = _eventFilter.FilterByMinAge(events.AsQueryable(), 18).ToList(); + + // Assert + Assert.Equal(2, result.Count); + Assert.Contains(events[0], result); + Assert.Contains(events[2], result); + } + + [Fact] + public void FilterByMaxAge_ShouldReturnMatchingEvents() + { + // Arrange + var events = GetTestEvents(); + + // Act + var result = _eventFilter.FilterByMaxAge(events.AsQueryable(), 18).ToList(); + + // Assert + Assert.Equal(2, result.Count); + Assert.Contains(events[0], result); + Assert.Contains(events[1], result); + } +} diff --git a/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs b/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs new file mode 100644 index 0000000..dbdc936 --- /dev/null +++ b/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs @@ -0,0 +1,16 @@ +using TickAPI.Events.Models; + +namespace TickAPI.Events.Abstractions; + +public interface IEventFilter +{ + IQueryable FilterByName(IQueryable events, string name); + IQueryable FilterByDescription(IQueryable events, string description); + IQueryable FilterByStartDate(IQueryable events, DateTime startDate); + IQueryable FilterByEndDate(IQueryable events, DateTime endDate); + IQueryable FilterByMinPrice(IQueryable events, decimal minPrice); + IQueryable FilterByMaxPrice(IQueryable events, decimal maxPrice); + IQueryable FilterByMinAge(IQueryable events, uint minAge); + IQueryable FilterByMaxAge(IQueryable events, uint maxAge); + // TODO: add filters for address and categories +} diff --git a/TickAPI/TickAPI/Events/Services/EventFilter.cs b/TickAPI/TickAPI/Events/Services/EventFilter.cs new file mode 100644 index 0000000..77d4c76 --- /dev/null +++ b/TickAPI/TickAPI/Events/Services/EventFilter.cs @@ -0,0 +1,49 @@ +using TickAPI.Events.Abstractions; +using TickAPI.Events.Models; + +namespace TickAPI.Events.Services; + +public class EventFilter : IEventFilter +{ + + public IQueryable FilterByName(IQueryable events, string name) + { + return events.Where(e => e.Name.Contains(name, StringComparison.CurrentCultureIgnoreCase)); + } + + public IQueryable FilterByDescription(IQueryable events, string description) + + { + return events.Where(e => e.Description.Contains(description, StringComparison.CurrentCultureIgnoreCase)); + } + + public IQueryable FilterByStartDate(IQueryable events, DateTime startDate) + { + return events.Where(e => e.StartDate.Date == startDate.Date); + } + + public IQueryable FilterByEndDate(IQueryable events, DateTime endDate) + { + return events.Where(e => e.EndDate.Date == endDate.Date); + } + + public IQueryable FilterByMinPrice(IQueryable events, decimal minPrice) + { + return events.Where(e => e.TicketTypes.All(t => t.Price >= minPrice)); + } + + public IQueryable FilterByMaxPrice(IQueryable events, decimal maxPrice) + { + return events.Where(e => e.TicketTypes.All(t => t.Price <= maxPrice)); + } + + public IQueryable FilterByMinAge(IQueryable events, uint minAge) + { + return events.Where(e => e.MinimumAge >= minAge); + } + + public IQueryable FilterByMaxAge(IQueryable events, uint maxAge) + { + return events.Where(e => e.MinimumAge <= maxAge); + } +} diff --git a/TickAPI/TickAPI/Program.cs b/TickAPI/TickAPI/Program.cs index 08779cd..d98aa53 100644 --- a/TickAPI/TickAPI/Program.cs +++ b/TickAPI/TickAPI/Program.cs @@ -92,6 +92,7 @@ // Add event services. builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); // Add address services. builder.Services.AddScoped(); From 94c590a1f71f453047200f556e61ee49f1cf2e49 Mon Sep 17 00:00:00 2001 From: kTrzcinskii Date: Thu, 10 Apr 2025 19:26:01 +0200 Subject: [PATCH 02/33] Remove unnecessary import --- TickAPI/TickAPI/Addresses/Models/Address.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/TickAPI/TickAPI/Addresses/Models/Address.cs b/TickAPI/TickAPI/Addresses/Models/Address.cs index 1aca9d9..f6e705b 100644 --- a/TickAPI/TickAPI/Addresses/Models/Address.cs +++ b/TickAPI/TickAPI/Addresses/Models/Address.cs @@ -1,5 +1,4 @@ namespace TickAPI.Addresses.Models; -using TickAPI.Events.DTOs.Request; public class Address { public Guid Id { get; set; } From 5697084fa979be9444688bee9233424512739b82 Mon Sep 17 00:00:00 2001 From: kTrzcinskii Date: Thu, 10 Apr 2025 19:26:38 +0200 Subject: [PATCH 03/33] Add functions for filtering by event's address --- .../Events/Services/EventFilterTests.cs | 116 +++++++++++++++++- .../Events/Abstractions/IEventFilter.cs | 5 + .../TickAPI/Events/Services/EventFilter.cs | 30 ++++- 3 files changed, 149 insertions(+), 2 deletions(-) diff --git a/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs b/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs index 4e2735d..90a0924 100644 --- a/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs +++ b/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs @@ -1,4 +1,5 @@ -using TickAPI.Events.Models; +using TickAPI.Addresses.Models; +using TickAPI.Events.Models; using TickAPI.Events.Services; using TickAPI.TicketTypes.Models; @@ -17,6 +18,15 @@ private static List GetTestEvents() => StartDate = new DateTime(2025, 5, 1, 18, 0, 0), EndDate = new DateTime(2025, 5, 1, 22, 0, 0), MinimumAge = 18, + Address = new Address + { + Country = "Poland", + City = "Warsaw", + Street = "Marszałkowska", + HouseNumber = 12, + FlatNumber = 5, + PostalCode = "00-001" + }, TicketTypes = new List { new TicketType { Price = 100 }, @@ -31,6 +41,15 @@ private static List GetTestEvents() => StartDate = new DateTime(2025, 6, 1), EndDate = new DateTime(2025, 6, 2), MinimumAge = 12, + Address = new Address + { + Country = "Germany", + City = "Berlin", + Street = "Unter den Linden", + HouseNumber = 44, + FlatNumber = 10, + PostalCode = "10117" + }, TicketTypes = new List { new TicketType { Price = 50 } @@ -44,6 +63,15 @@ private static List GetTestEvents() => StartDate = new DateTime(2025, 5, 1), EndDate = new DateTime(2025, 5, 3), MinimumAge = 21, + Address = new Address + { + Country = "Poland", + City = "Krakow", + Street = "Długa", + HouseNumber = 7, + FlatNumber = 3, + PostalCode = "31-147" + }, TicketTypes = new List { new TicketType { Price = 200 }, @@ -168,4 +196,90 @@ public void FilterByMaxAge_ShouldReturnMatchingEvents() Assert.Contains(events[0], result); Assert.Contains(events[1], result); } + + [Fact] + public void FilterByAddressCountry_ShouldReturnMatchingEvents() + { + // Arrange + var events = GetTestEvents(); + + // Act + var result = _eventFilter.FilterByAddressCountry(events.AsQueryable(), "poland").ToList(); + + // Assert + Assert.Equal(2, result.Count); + Assert.Contains(events[0], result); + Assert.Contains(events[2], result); + } + + [Fact] + public void FilterByAddressCity_ShouldReturnMatchingEvents() + { + // Arrange + var events = GetTestEvents(); + + // Act + var result = _eventFilter.FilterByAddressCity(events.AsQueryable(), "berlin").ToList(); + + // Assert + Assert.Single(result); + Assert.Contains(events[1], result); + } + + [Fact] + public void FilterByAddressStreet_WithAllParameters_ShouldReturnMatchingEvents() + { + // Arrange + var events = GetTestEvents(); + + // Act + var result = _eventFilter.FilterByAddressStreet(events.AsQueryable(), "marszałkowska", 12, 5).ToList(); + + // Assert + Assert.Single(result); + Assert.Contains(events[0], result); + } + + [Fact] + public void FilterByAddressStreet_WithoutFlatNumber_ShouldReturnMatchingEvents() + { + // Arrange + var events = GetTestEvents(); + + // Act + var result = _eventFilter.FilterByAddressStreet(events.AsQueryable(), "marszałkowska", 12).ToList(); + + // Assert + Assert.Single(result); + Assert.Contains(events[0], result); + } + + [Fact] + public void FilterByAddressStreet_WithStreetOnly_ShouldReturnMatchingEvents() + { + // Arrange + var events = GetTestEvents(); + + // Act + var result = _eventFilter.FilterByAddressStreet(events.AsQueryable(), "długa").ToList(); + + // Assert + Assert.Single(result); + Assert.Contains(events[2], result); + } + + [Fact] + public void FilterByAddressPostalCode_ShouldReturnMatchingEvents() + { + // Arrange + var events = GetTestEvents(); + + // Act + var result = _eventFilter.FilterByAddressPostalCode(events.AsQueryable(), "10117").ToList(); + + // Assert + Assert.Single(result); + Assert.Contains(events[1], result); + } + } diff --git a/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs b/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs index dbdc936..befd84d 100644 --- a/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs +++ b/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs @@ -12,5 +12,10 @@ public interface IEventFilter IQueryable FilterByMaxPrice(IQueryable events, decimal maxPrice); IQueryable FilterByMinAge(IQueryable events, uint minAge); IQueryable FilterByMaxAge(IQueryable events, uint maxAge); + IQueryable FilterByAddressCountry(IQueryable events, string country); + IQueryable FilterByAddressCity(IQueryable events, string city); + IQueryable FilterByAddressStreet(IQueryable events, string street, uint? houseNumber, uint? flatNumber); + IQueryable FilterByAddressPostalCode(IQueryable events, string postalCode); + // TODO: add filters for address and categories } diff --git a/TickAPI/TickAPI/Events/Services/EventFilter.cs b/TickAPI/TickAPI/Events/Services/EventFilter.cs index 77d4c76..9cb2208 100644 --- a/TickAPI/TickAPI/Events/Services/EventFilter.cs +++ b/TickAPI/TickAPI/Events/Services/EventFilter.cs @@ -5,7 +5,6 @@ namespace TickAPI.Events.Services; public class EventFilter : IEventFilter { - public IQueryable FilterByName(IQueryable events, string name) { return events.Where(e => e.Name.Contains(name, StringComparison.CurrentCultureIgnoreCase)); @@ -46,4 +45,33 @@ public IQueryable FilterByMaxAge(IQueryable events, uint maxAge) { return events.Where(e => e.MinimumAge <= maxAge); } + + public IQueryable FilterByAddressCountry(IQueryable events, string country) + { + return events.Where(e => e.Address.Country.Contains(country, StringComparison.CurrentCultureIgnoreCase)); + } + + public IQueryable FilterByAddressCity(IQueryable events, string city) + { + return events.Where(e => e.Address.City.Contains(city, StringComparison.CurrentCultureIgnoreCase)); + } + + public IQueryable FilterByAddressStreet(IQueryable events, string street, uint? houseNumber = null, uint? flatNumber = null) + { + var result = events.Where(e => e.Address.Street != null && e.Address.Street.Contains(street, StringComparison.CurrentCultureIgnoreCase)); + if (houseNumber != null) + { + result = result.Where(e => e.Address.HouseNumber != null && e.Address.HouseNumber == houseNumber); + } + if (flatNumber != null) + { + result = result.Where(e => e.Address.FlatNumber != null && e.Address.FlatNumber == flatNumber); + } + return result; + } + + public IQueryable FilterByAddressPostalCode(IQueryable events, string postalCode) + { + return events.Where(e => e.Address.PostalCode == postalCode); + } } From d6930a6e2fde27b4d69646b477febc0fdc743479 Mon Sep 17 00:00:00 2001 From: kTrzcinskii Date: Thu, 10 Apr 2025 19:33:03 +0200 Subject: [PATCH 04/33] Add function for filtering by event's categories --- .../Events/Services/EventFilterTests.cs | 31 +++++++++++++++++++ .../Events/Abstractions/IEventFilter.cs | 3 +- .../TickAPI/Events/Services/EventFilter.cs | 5 +++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs b/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs index 90a0924..445b3aa 100644 --- a/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs +++ b/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs @@ -1,4 +1,5 @@ using TickAPI.Addresses.Models; +using TickAPI.Categories.Models; using TickAPI.Events.Models; using TickAPI.Events.Services; using TickAPI.TicketTypes.Models; @@ -31,6 +32,11 @@ private static List GetTestEvents() => { new TicketType { Price = 100 }, new TicketType { Price = 120 } + }, + Categories = new List + { + new Category { Name = "Music" }, + new Category { Name = "Rock" } } }, @@ -53,6 +59,11 @@ private static List GetTestEvents() => TicketTypes = new List { new TicketType { Price = 50 } + }, + Categories = new List + { + new Category { Name = "Music" }, + new Category { Name = "Jazz" } } }, @@ -76,6 +87,11 @@ private static List GetTestEvents() => { new TicketType { Price = 200 }, new TicketType { Price = 150 } + }, + Categories = new List + { + new Category { Name = "Technology" }, + new Category { Name = "Development" } } } ]; @@ -282,4 +298,19 @@ public void FilterByAddressPostalCode_ShouldReturnMatchingEvents() Assert.Contains(events[1], result); } + [Fact] + public void FilterByCategoriesNames_ShouldReturnMatchingEvents() + { + // Arrange + var events = GetTestEvents(); + + // Act + var result = _eventFilter.FilterByCategoriesNames(events.AsQueryable(), ["Jazz", "Technology"]).ToList(); + + // Assert + Assert.Equal(2, result.Count); + Assert.Contains(events[1], result); + Assert.Contains(events[2], result); + } + } diff --git a/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs b/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs index befd84d..350c8cf 100644 --- a/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs +++ b/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs @@ -16,6 +16,5 @@ public interface IEventFilter IQueryable FilterByAddressCity(IQueryable events, string city); IQueryable FilterByAddressStreet(IQueryable events, string street, uint? houseNumber, uint? flatNumber); IQueryable FilterByAddressPostalCode(IQueryable events, string postalCode); - - // TODO: add filters for address and categories + IQueryable FilterByCategoriesNames(IQueryable events, IEnumerable categoriesNames); } diff --git a/TickAPI/TickAPI/Events/Services/EventFilter.cs b/TickAPI/TickAPI/Events/Services/EventFilter.cs index 9cb2208..7145971 100644 --- a/TickAPI/TickAPI/Events/Services/EventFilter.cs +++ b/TickAPI/TickAPI/Events/Services/EventFilter.cs @@ -74,4 +74,9 @@ public IQueryable FilterByAddressPostalCode(IQueryable events, str { return events.Where(e => e.Address.PostalCode == postalCode); } + + public IQueryable FilterByCategoriesNames(IQueryable events, IEnumerable categoriesNames) + { + return events.Where(e => e.Categories.Any(c => categoriesNames.Contains(c.Name))); + } } From 8d77bbecf5bbb2ed23601992586a59a9ba5e9989 Mon Sep 17 00:00:00 2001 From: kTrzcinskii Date: Sun, 13 Apr 2025 17:19:26 +0200 Subject: [PATCH 05/33] Store events inside `EventFilter` --- .../Events/Services/EventFilterTests.cs | 62 ++++++++++++----- .../Events/Abstractions/IEventFilter.cs | 27 ++++---- .../TickAPI/Events/Services/EventFilter.cs | 66 +++++++++++-------- 3 files changed, 98 insertions(+), 57 deletions(-) diff --git a/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs b/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs index 445b3aa..d908349 100644 --- a/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs +++ b/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs @@ -8,8 +8,6 @@ namespace TickAPI.Tests.Events.Services; public class EventFilterTests { - private readonly EventFilter _eventFilter = new EventFilter(); - private static List GetTestEvents() => [ new Event @@ -103,7 +101,9 @@ public void FilterByName_ShouldReturnMatchingEvents() var events = GetTestEvents(); // Act - var result = _eventFilter.FilterByName(events.AsQueryable(), "concert").ToList(); + var eventFilter = new EventFilter(events.AsQueryable()); + eventFilter.FilterByName("concert"); + var result = eventFilter.GetEvents().ToList(); // Assert Assert.Equal(2, result.Count); @@ -118,7 +118,9 @@ public void FilterByDescription_ShouldReturnMatchingEvents() var events = GetTestEvents(); // Act - var result = _eventFilter.FilterByDescription(events.AsQueryable(), "tech").ToList(); + var eventFilter = new EventFilter(events.AsQueryable()); + eventFilter.FilterByDescription("tech"); + var result = eventFilter.GetEvents().ToList(); // Assert Assert.Single(result); @@ -132,7 +134,9 @@ public void FilterByStartDate_ShouldReturnMatchingEvents() var events = GetTestEvents(); // Act - var result = _eventFilter.FilterByStartDate(events.AsQueryable(), new DateTime(2025, 5, 1)).ToList(); + var eventFilter = new EventFilter(events.AsQueryable()); + eventFilter.FilterByStartDate(new DateTime(2025, 5, 1)); + var result = eventFilter.GetEvents().ToList(); // Assert Assert.Equal(2, result.Count); @@ -147,7 +151,9 @@ public void FilterByEndDate_ShouldReturnMatchingEvents() var events = GetTestEvents(); // Act - var result = _eventFilter.FilterByEndDate(events.AsQueryable(), new DateTime(2025, 5, 1, 22, 0, 0)).ToList(); + var eventFilter = new EventFilter(events.AsQueryable()); + eventFilter.FilterByEndDate(new DateTime(2025, 5, 1, 22, 0, 0)); + var result = eventFilter.GetEvents().ToList(); // Assert Assert.Single(result); @@ -161,7 +167,9 @@ public void FilterByMinPrice_ShouldReturnMatchingEvents() var events = GetTestEvents(); // Act - var result = _eventFilter.FilterByMinPrice(events.AsQueryable(), 100).ToList(); + var eventFilter = new EventFilter(events.AsQueryable()); + eventFilter.FilterByMinPrice(100); + var result = eventFilter.GetEvents().ToList(); // Assert Assert.Equal(2, result.Count); @@ -176,7 +184,9 @@ public void FilterByMaxPrice_ShouldReturnMatchingEvents() var events = GetTestEvents(); // Act - var result = _eventFilter.FilterByMaxPrice(events.AsQueryable(), 100).ToList(); + var eventFilter = new EventFilter(events.AsQueryable()); + eventFilter.FilterByMaxPrice(100); + var result = eventFilter.GetEvents().ToList(); // Assert Assert.Single(result); @@ -190,7 +200,9 @@ public void FilterByMinAge_ShouldReturnMatchingEvents() var events = GetTestEvents(); // Act - var result = _eventFilter.FilterByMinAge(events.AsQueryable(), 18).ToList(); + var eventFilter = new EventFilter(events.AsQueryable()); + eventFilter.FilterByMinAge(18); + var result = eventFilter.GetEvents().ToList(); // Assert Assert.Equal(2, result.Count); @@ -205,7 +217,9 @@ public void FilterByMaxAge_ShouldReturnMatchingEvents() var events = GetTestEvents(); // Act - var result = _eventFilter.FilterByMaxAge(events.AsQueryable(), 18).ToList(); + var eventFilter = new EventFilter(events.AsQueryable()); + eventFilter.FilterByMaxAge(18); + var result = eventFilter.GetEvents().ToList(); // Assert Assert.Equal(2, result.Count); @@ -220,7 +234,9 @@ public void FilterByAddressCountry_ShouldReturnMatchingEvents() var events = GetTestEvents(); // Act - var result = _eventFilter.FilterByAddressCountry(events.AsQueryable(), "poland").ToList(); + var eventFilter = new EventFilter(events.AsQueryable()); + eventFilter.FilterByAddressCountry("poland"); + var result = eventFilter.GetEvents().ToList(); // Assert Assert.Equal(2, result.Count); @@ -235,7 +251,9 @@ public void FilterByAddressCity_ShouldReturnMatchingEvents() var events = GetTestEvents(); // Act - var result = _eventFilter.FilterByAddressCity(events.AsQueryable(), "berlin").ToList(); + var eventFilter = new EventFilter(events.AsQueryable()); + eventFilter.FilterByAddressCity("berlin"); + var result = eventFilter.GetEvents().ToList(); // Assert Assert.Single(result); @@ -249,7 +267,9 @@ public void FilterByAddressStreet_WithAllParameters_ShouldReturnMatchingEvents() var events = GetTestEvents(); // Act - var result = _eventFilter.FilterByAddressStreet(events.AsQueryable(), "marszałkowska", 12, 5).ToList(); + var eventFilter = new EventFilter(events.AsQueryable()); + eventFilter.FilterByAddressStreet("marszałkowska", 12, 5); + var result = eventFilter.GetEvents().ToList(); // Assert Assert.Single(result); @@ -263,7 +283,9 @@ public void FilterByAddressStreet_WithoutFlatNumber_ShouldReturnMatchingEvents() var events = GetTestEvents(); // Act - var result = _eventFilter.FilterByAddressStreet(events.AsQueryable(), "marszałkowska", 12).ToList(); + var eventFilter = new EventFilter(events.AsQueryable()); + eventFilter.FilterByAddressStreet("marszałkowska", 12); + var result = eventFilter.GetEvents().ToList(); // Assert Assert.Single(result); @@ -277,7 +299,9 @@ public void FilterByAddressStreet_WithStreetOnly_ShouldReturnMatchingEvents() var events = GetTestEvents(); // Act - var result = _eventFilter.FilterByAddressStreet(events.AsQueryable(), "długa").ToList(); + var eventFilter = new EventFilter(events.AsQueryable()); + eventFilter.FilterByAddressStreet("długa"); + var result = eventFilter.GetEvents().ToList(); // Assert Assert.Single(result); @@ -291,7 +315,9 @@ public void FilterByAddressPostalCode_ShouldReturnMatchingEvents() var events = GetTestEvents(); // Act - var result = _eventFilter.FilterByAddressPostalCode(events.AsQueryable(), "10117").ToList(); + var eventFilter = new EventFilter(events.AsQueryable()); + eventFilter.FilterByAddressPostalCode("10117"); + var result = eventFilter.GetEvents().ToList(); // Assert Assert.Single(result); @@ -305,7 +331,9 @@ public void FilterByCategoriesNames_ShouldReturnMatchingEvents() var events = GetTestEvents(); // Act - var result = _eventFilter.FilterByCategoriesNames(events.AsQueryable(), ["Jazz", "Technology"]).ToList(); + var eventFilter = new EventFilter(events.AsQueryable()); + eventFilter.FilterByCategoriesNames(["Jazz", "Technology"]); + var result = eventFilter.GetEvents().ToList(); // Assert Assert.Equal(2, result.Count); diff --git a/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs b/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs index 350c8cf..686ae3e 100644 --- a/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs +++ b/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs @@ -4,17 +4,18 @@ namespace TickAPI.Events.Abstractions; public interface IEventFilter { - IQueryable FilterByName(IQueryable events, string name); - IQueryable FilterByDescription(IQueryable events, string description); - IQueryable FilterByStartDate(IQueryable events, DateTime startDate); - IQueryable FilterByEndDate(IQueryable events, DateTime endDate); - IQueryable FilterByMinPrice(IQueryable events, decimal minPrice); - IQueryable FilterByMaxPrice(IQueryable events, decimal maxPrice); - IQueryable FilterByMinAge(IQueryable events, uint minAge); - IQueryable FilterByMaxAge(IQueryable events, uint maxAge); - IQueryable FilterByAddressCountry(IQueryable events, string country); - IQueryable FilterByAddressCity(IQueryable events, string city); - IQueryable FilterByAddressStreet(IQueryable events, string street, uint? houseNumber, uint? flatNumber); - IQueryable FilterByAddressPostalCode(IQueryable events, string postalCode); - IQueryable FilterByCategoriesNames(IQueryable events, IEnumerable categoriesNames); + IQueryable GetEvents(); + void FilterByName(string name); + void FilterByDescription(string description); + void FilterByStartDate(DateTime startDate); + void FilterByEndDate(DateTime endDate); + void FilterByMinPrice(decimal minPrice); + void FilterByMaxPrice(decimal maxPrice); + void FilterByMinAge(uint minAge); + void FilterByMaxAge(uint maxAge); + void FilterByAddressCountry(string country); + void FilterByAddressCity(string city); + void FilterByAddressStreet(string street, uint? houseNumber, uint? flatNumber); + void FilterByAddressPostalCode(string postalCode); + void FilterByCategoriesNames(IEnumerable categoriesNames); } diff --git a/TickAPI/TickAPI/Events/Services/EventFilter.cs b/TickAPI/TickAPI/Events/Services/EventFilter.cs index 7145971..ec4c627 100644 --- a/TickAPI/TickAPI/Events/Services/EventFilter.cs +++ b/TickAPI/TickAPI/Events/Services/EventFilter.cs @@ -5,60 +5,72 @@ namespace TickAPI.Events.Services; public class EventFilter : IEventFilter { - public IQueryable FilterByName(IQueryable events, string name) + private IQueryable _events; + + public EventFilter(IQueryable events) + { + _events = events; + } + + public IQueryable GetEvents() + { + return _events; + } + + public void FilterByName(string name) { - return events.Where(e => e.Name.Contains(name, StringComparison.CurrentCultureIgnoreCase)); + _events = _events.Where(e => e.Name.Contains(name, StringComparison.CurrentCultureIgnoreCase)); } - public IQueryable FilterByDescription(IQueryable events, string description) + public void FilterByDescription(string description) { - return events.Where(e => e.Description.Contains(description, StringComparison.CurrentCultureIgnoreCase)); + _events = _events.Where(e => e.Description.Contains(description, StringComparison.CurrentCultureIgnoreCase)); } - public IQueryable FilterByStartDate(IQueryable events, DateTime startDate) + public void FilterByStartDate(DateTime startDate) { - return events.Where(e => e.StartDate.Date == startDate.Date); + _events = _events.Where(e => e.StartDate.Date == startDate.Date); } - public IQueryable FilterByEndDate(IQueryable events, DateTime endDate) + public void FilterByEndDate(DateTime endDate) { - return events.Where(e => e.EndDate.Date == endDate.Date); + _events = _events.Where(e => e.EndDate.Date == endDate.Date); } - public IQueryable FilterByMinPrice(IQueryable events, decimal minPrice) + public void FilterByMinPrice(decimal minPrice) { - return events.Where(e => e.TicketTypes.All(t => t.Price >= minPrice)); + _events = _events.Where(e => e.TicketTypes.All(t => t.Price >= minPrice)); } - public IQueryable FilterByMaxPrice(IQueryable events, decimal maxPrice) + public void FilterByMaxPrice(decimal maxPrice) { - return events.Where(e => e.TicketTypes.All(t => t.Price <= maxPrice)); + _events = _events.Where(e => e.TicketTypes.All(t => t.Price <= maxPrice)); } - public IQueryable FilterByMinAge(IQueryable events, uint minAge) + public void FilterByMinAge(uint minAge) { - return events.Where(e => e.MinimumAge >= minAge); + _events = _events.Where(e => e.MinimumAge >= minAge); } - public IQueryable FilterByMaxAge(IQueryable events, uint maxAge) + public void FilterByMaxAge(uint maxAge) { - return events.Where(e => e.MinimumAge <= maxAge); + _events = _events.Where(e => e.MinimumAge <= maxAge); } - public IQueryable FilterByAddressCountry(IQueryable events, string country) + public void FilterByAddressCountry(string country) { - return events.Where(e => e.Address.Country.Contains(country, StringComparison.CurrentCultureIgnoreCase)); + _events = _events.Where(e => e.Address.Country.Contains(country, StringComparison.CurrentCultureIgnoreCase)); } - public IQueryable FilterByAddressCity(IQueryable events, string city) + public void FilterByAddressCity(string city) { - return events.Where(e => e.Address.City.Contains(city, StringComparison.CurrentCultureIgnoreCase)); + _events = _events.Where(e => e.Address.City.Contains(city, StringComparison.CurrentCultureIgnoreCase)); } - public IQueryable FilterByAddressStreet(IQueryable events, string street, uint? houseNumber = null, uint? flatNumber = null) + public void FilterByAddressStreet(string street, uint? houseNumber = null, uint? flatNumber = null) { - var result = events.Where(e => e.Address.Street != null && e.Address.Street.Contains(street, StringComparison.CurrentCultureIgnoreCase)); + var result = _events.Where(e => e.Address.Street != null && e.Address.Street.Contains(street, StringComparison.CurrentCultureIgnoreCase)); if (houseNumber != null) { result = result.Where(e => e.Address.HouseNumber != null && e.Address.HouseNumber == houseNumber); @@ -67,16 +79,16 @@ public IQueryable FilterByAddressStreet(IQueryable events, string { result = result.Where(e => e.Address.FlatNumber != null && e.Address.FlatNumber == flatNumber); } - return result; + _events = result; } - public IQueryable FilterByAddressPostalCode(IQueryable events, string postalCode) + public void FilterByAddressPostalCode(string postalCode) { - return events.Where(e => e.Address.PostalCode == postalCode); + _events = _events.Where(e => e.Address.PostalCode == postalCode); } - public IQueryable FilterByCategoriesNames(IQueryable events, IEnumerable categoriesNames) + public void FilterByCategoriesNames(IEnumerable categoriesNames) { - return events.Where(e => e.Categories.Any(c => categoriesNames.Contains(c.Name))); + _events = _events.Where(e => e.Categories.Any(c => categoriesNames.Contains(c.Name))); } } From 9ebc5d3b7bc5509698327a90f6bdefe89cedae90 Mon Sep 17 00:00:00 2001 From: kubapoke Date: Sun, 13 Apr 2025 17:39:12 +0200 Subject: [PATCH 06/33] removed the empty line --- TickAPI/TickAPI/Events/Services/EventFilter.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/TickAPI/TickAPI/Events/Services/EventFilter.cs b/TickAPI/TickAPI/Events/Services/EventFilter.cs index ec4c627..86c8aaa 100644 --- a/TickAPI/TickAPI/Events/Services/EventFilter.cs +++ b/TickAPI/TickAPI/Events/Services/EventFilter.cs @@ -23,7 +23,6 @@ public void FilterByName(string name) } public void FilterByDescription(string description) - { _events = _events.Where(e => e.Description.Contains(description, StringComparison.CurrentCultureIgnoreCase)); } From 88b2aba1d5e4898f63ca33ad08162b3622a31802 Mon Sep 17 00:00:00 2001 From: kubapoke Date: Sun, 13 Apr 2025 17:53:54 +0200 Subject: [PATCH 07/33] added min/max start/end date filtration methods --- .../Events/Services/EventFilterTests.cs | 66 +++++++++++++++++++ .../Events/Abstractions/IEventFilter.cs | 4 ++ .../TickAPI/Events/Services/EventFilter.cs | 20 ++++++ 3 files changed, 90 insertions(+) diff --git a/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs b/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs index d908349..761a72a 100644 --- a/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs +++ b/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs @@ -144,6 +144,39 @@ public void FilterByStartDate_ShouldReturnMatchingEvents() Assert.Contains(events[2], result); } + [Fact] + public void FilterByMinStartDate_ShouldReturnMatchingEvents() + { + // Arrange + var events = GetTestEvents(); + + // Act + var eventFilter = new EventFilter(events.AsQueryable()); + eventFilter.FilterByMinStartDate(new DateTime(2025, 5, 15)); + var result = eventFilter.GetEvents().ToList(); + + // Assert + Assert.Single(result); + Assert.Contains(events[1], result); + } + + [Fact] + public void FilterByMaxStartDate_ShouldReturnMatchingEvents() + { + // Arrange + var events = GetTestEvents(); + + // Act + var eventFilter = new EventFilter(events.AsQueryable()); + eventFilter.FilterByMaxStartDate(new DateTime(2025, 5, 15)); + var result = eventFilter.GetEvents().ToList(); + + // Assert + Assert.Equal(2, result.Count); + Assert.Contains(events[0], result); + Assert.Contains(events[2], result); + } + [Fact] public void FilterByEndDate_ShouldReturnMatchingEvents() { @@ -160,6 +193,39 @@ public void FilterByEndDate_ShouldReturnMatchingEvents() Assert.Contains(events[0], result); } + [Fact] + public void FilterByMinEndDate_ShouldReturnMatchingEvents() + { + // Arrange + var events = GetTestEvents(); + + // Act + var eventFilter = new EventFilter(events.AsQueryable()); + eventFilter.FilterByMinEndDate(new DateTime(2025, 5, 15)); + var result = eventFilter.GetEvents().ToList(); + + // Assert + Assert.Single(result); + Assert.Contains(events[1], result); + } + + [Fact] + public void FilterByMaxEndDate_ShouldReturnMatchingEvents() + { + // Arrange + var events = GetTestEvents(); + + // Act + var eventFilter = new EventFilter(events.AsQueryable()); + eventFilter.FilterByMaxEndDate(new DateTime(2025, 5, 15)); + var result = eventFilter.GetEvents().ToList(); + + // Assert + Assert.Equal(2, result.Count); + Assert.Contains(events[0], result); + Assert.Contains(events[2], result); + } + [Fact] public void FilterByMinPrice_ShouldReturnMatchingEvents() { diff --git a/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs b/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs index 686ae3e..369b10d 100644 --- a/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs +++ b/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs @@ -8,7 +8,11 @@ public interface IEventFilter void FilterByName(string name); void FilterByDescription(string description); void FilterByStartDate(DateTime startDate); + void FilterByMinStartDate(DateTime startDate); + void FilterByMaxStartDate(DateTime startDate); void FilterByEndDate(DateTime endDate); + void FilterByMinEndDate(DateTime endDate); + void FilterByMaxEndDate(DateTime endDate); void FilterByMinPrice(decimal minPrice); void FilterByMaxPrice(decimal maxPrice); void FilterByMinAge(uint minAge); diff --git a/TickAPI/TickAPI/Events/Services/EventFilter.cs b/TickAPI/TickAPI/Events/Services/EventFilter.cs index 86c8aaa..6e55c9c 100644 --- a/TickAPI/TickAPI/Events/Services/EventFilter.cs +++ b/TickAPI/TickAPI/Events/Services/EventFilter.cs @@ -32,11 +32,31 @@ public void FilterByStartDate(DateTime startDate) _events = _events.Where(e => e.StartDate.Date == startDate.Date); } + public void FilterByMinStartDate(DateTime startDate) + { + _events = _events.Where(e => e.StartDate.Date >= startDate.Date); + } + + public void FilterByMaxStartDate(DateTime startDate) + { + _events = _events.Where(e => e.StartDate.Date <= startDate.Date); + } + public void FilterByEndDate(DateTime endDate) { _events = _events.Where(e => e.EndDate.Date == endDate.Date); } + public void FilterByMinEndDate(DateTime endDate) + { + _events = _events.Where(e => e.EndDate.Date >= endDate.Date); + } + + public void FilterByMaxEndDate(DateTime endDate) + { + _events = _events.Where(e => e.EndDate.Date <= endDate.Date); + } + public void FilterByMinPrice(decimal minPrice) { _events = _events.Where(e => e.TicketTypes.All(t => t.Price >= minPrice)); From 282c995c39fc3b0c658c763dfa3d4f2afeca3b9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Mon, 14 Apr 2025 13:57:00 +0200 Subject: [PATCH 08/33] resolve merge conflicts --- .../Controllers/EventControllerTests.cs | 20 ++++-- .../Events/Services/EventServiceTests.cs | 66 ++++++++++++++----- .../DTOs/Request/CreateEventCategoryDto.cs | 6 ++ .../Events/Abstractions/IEventService.cs | 4 +- .../Events/Controllers/EventController.cs | 4 +- .../Events/DTOs/Request/CreateEventDto.cs | 5 +- .../TickAPI/Events/Services/EventService.cs | 22 ++++++- 7 files changed, 99 insertions(+), 28 deletions(-) create mode 100644 TickAPI/TickAPI/Categories/DTOs/Request/CreateEventCategoryDto.cs diff --git a/TickAPI/TickAPI.Tests/Events/Controllers/EventControllerTests.cs b/TickAPI/TickAPI.Tests/Events/Controllers/EventControllerTests.cs index 8c788b1..c1f2947 100644 --- a/TickAPI/TickAPI.Tests/Events/Controllers/EventControllerTests.cs +++ b/TickAPI/TickAPI.Tests/Events/Controllers/EventControllerTests.cs @@ -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; @@ -30,12 +31,17 @@ public async Task CreateEvent_WhenDataIsValid_ShouldReturnSuccess() const string email = "123@mail.com"; const EventStatus eventStatus = EventStatus.TicketsAvailable; Guid id = Guid.NewGuid(); + List categories = + [ + new CreateEventCategoryDto("concert"), + new CreateEventCategoryDto("bear metal") + ]; 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, eventStatus, createAddress); var eventServiceMock = new Mock(); eventServiceMock - .Setup(m => m.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, eventStatus, email)) + .Setup(m => m.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, categories ,eventStatus, email)) .ReturnsAsync(Result.Success(new Event())); var claims = new List @@ -79,6 +85,12 @@ 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 categories = + [ + new CreateEventCategoryDto("concert"), + new CreateEventCategoryDto("bear metal") + ]; CreateAddressDto createAddress = new CreateAddressDto("United States", "New York", "Main st", 20, null, "00-000"); var eventServiceMock = new Mock(); @@ -97,8 +109,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, eventStatus, createAddress)); // Assert var result = Assert.IsType>(res); diff --git a/TickAPI/TickAPI.Tests/Events/Services/EventServiceTests.cs b/TickAPI/TickAPI.Tests/Events/Services/EventServiceTests.cs index 59bdd8a..a14f429 100644 --- a/TickAPI/TickAPI.Tests/Events/Services/EventServiceTests.cs +++ b/TickAPI/TickAPI.Tests/Events/Services/EventServiceTests.cs @@ -6,6 +6,8 @@ using TickAPI.Addresses.Models; using TickAPI.Common.Pagination.Abstractions; using TickAPI.Common.Pagination.Responses; +using TickAPI.Categories.Abstractions; +using TickAPI.Categories.DTOs.Request; using TickAPI.Events.Models; using TickAPI.Organizers.Abstractions; using TickAPI.Organizers.Models; @@ -31,6 +33,11 @@ public async Task CreateNewEventAsync_WhenEventDataIsValid_ShouldReturnNewEvent( string organizerEmail = "123@mail.com"; EventStatus eventStatus = EventStatus.TicketsAvailable; Guid id = Guid.NewGuid(); + List categories = + [ + new CreateEventCategoryDto("concert"), + new CreateEventCategoryDto("bear metal") + ]; CreateAddressDto createAddress = new CreateAddressDto("United States", "New York", "Main st", 20, null, "00-000"); var eventRepositoryMock = new Mock(); @@ -57,13 +64,14 @@ public async Task CreateNewEventAsync_WhenEventDataIsValid_ShouldReturnNewEvent( var dateTimeServiceMock = new Mock(); dateTimeServiceMock.Setup(m => m.GetCurrentDateTime()).Returns(new DateTime(2003, 7, 11)); + + var categoryRepositoryMock = new Mock(); var paginationServiceMock = new Mock(); - - var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, dateTimeServiceMock.Object, paginationServiceMock.Object); - // Act - var result = await sut.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, eventStatus, organizerEmail); + var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); + // act + var result = await sut.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, categories, eventStatus, organizerEmail); // Assert Assert.True(result.IsSuccess); @@ -88,6 +96,11 @@ public async Task CreateNewEventAsync_WhenEndDateIsBeforeStartDate_ShouldReturnB string organizerEmail = "123@mail.com"; EventStatus eventStatus = EventStatus.TicketsAvailable; Guid id = Guid.NewGuid(); + List categories = + [ + new CreateEventCategoryDto("concert"), + new CreateEventCategoryDto("bear metal") + ]; CreateAddressDto createAddress = new CreateAddressDto("United States", "New York", "Main st", 20, null, "00-000"); var eventRepositoryMock = new Mock(); @@ -100,13 +113,16 @@ public async Task CreateNewEventAsync_WhenEndDateIsBeforeStartDate_ShouldReturnB var addressServiceMock = new Mock(); var dateTimeServiceMock = new Mock(); - + + var categoryRepositoryMock = new Mock(); + + + // act var paginationServiceMock = new Mock(); - var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, dateTimeServiceMock.Object, paginationServiceMock.Object); + var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); - // Act - var res = await sut.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, eventStatus, organizerEmail); + var res = await sut.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, categories, eventStatus, organizerEmail); // Assert Assert.False(res.IsSuccess); @@ -125,6 +141,12 @@ public async Task CreateNewEventAsync_WhenStartDateIsBeforeNow_ShouldReturnBadRe uint? minimumAge = 18; string organizerEmail = "123@mail.com"; EventStatus eventStatus = EventStatus.TicketsAvailable; + Guid id = Guid.NewGuid(); + List categories = + [ + new CreateEventCategoryDto("concert"), + new CreateEventCategoryDto("bear metal") + ]; CreateAddressDto createAddress = new CreateAddressDto("United States", "New York", "Main st", 20, null, "00-000"); var eventRepositoryMock = new Mock(); @@ -138,13 +160,15 @@ public async Task CreateNewEventAsync_WhenStartDateIsBeforeNow_ShouldReturnBadRe var dateTimeServiceMock = new Mock(); dateTimeServiceMock.Setup(m => m.GetCurrentDateTime()).Returns(new DateTime(2025, 5, 11)); - + + var categoryRepositoryMock = new Mock(); + + // act var paginationServiceMock = new Mock(); - var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, dateTimeServiceMock.Object, paginationServiceMock.Object); + var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); - // Act - var res = await sut.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, eventStatus, organizerEmail); + var res = await sut.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, categories, eventStatus, organizerEmail); // Assert Assert.False(res.IsSuccess); @@ -175,6 +199,7 @@ public async Task GetOrganizerEvents_WhenPaginationSucceeds_ShouldReturnPaginate var addressServiceMock = new Mock(); var dateTimeServiceMock = new Mock(); var paginationServiceMock = new Mock(); + var categoryRepositoryMock = new Mock(); var paginatedEvents = new PaginatedData( organizer.Events.Take(pageSize).ToList(), @@ -208,7 +233,7 @@ public async Task GetOrganizerEvents_WhenPaginationSucceeds_ShouldReturnPaginate )); var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, - dateTimeServiceMock.Object, paginationServiceMock.Object); + dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); // Act var result = await sut.GetOrganizerEventsAsync(organizer, page, pageSize); @@ -248,6 +273,7 @@ public async Task GetOrganizerEvents_WhenPaginationFails_ShouldPropagateError() var addressServiceMock = new Mock(); var dateTimeServiceMock = new Mock(); var paginationServiceMock = new Mock(); + var categoryRepositoryMock = new Mock(); var organizerEvents = organizer.Events.AsQueryable(); eventRepositoryMock.Setup(p => p.GetEventsByOranizer(organizer)).Returns(organizerEvents); @@ -257,7 +283,7 @@ public async Task GetOrganizerEvents_WhenPaginationFails_ShouldPropagateError() .ReturnsAsync(Result>.Failure(StatusCodes.Status400BadRequest, "Invalid page number")); var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, - dateTimeServiceMock.Object, paginationServiceMock.Object); + dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); // Act var result = await sut.GetOrganizerEventsAsync(organizer, page, pageSize); @@ -286,6 +312,7 @@ public async Task GetEventsAsync_WhenPaginationSucceeds_ShouldReturnPaginatedEve var addressServiceMock = new Mock(); var dateTimeServiceMock = new Mock(); var paginationServiceMock = new Mock(); + var categoryRepositoryMock = new Mock(); var paginatedEvents = new PaginatedData( events.Take(pageSize).ToList(), @@ -319,7 +346,7 @@ public async Task GetEventsAsync_WhenPaginationSucceeds_ShouldReturnPaginatedEve )); var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, - dateTimeServiceMock.Object, paginationServiceMock.Object); + dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); // Act var result = await sut.GetEventsAsync(page, pageSize); @@ -354,6 +381,7 @@ public async Task GetEventsAsync_WhenPaginationFails_ShouldPropagateError() var addressServiceMock = new Mock(); var dateTimeServiceMock = new Mock(); var paginationServiceMock = new Mock(); + var categoryRepositoryMock = new Mock(); var eventsQueryable = events.AsQueryable(); eventRepositoryMock.Setup(p => p.GetEvents()).Returns(eventsQueryable); @@ -363,7 +391,7 @@ public async Task GetEventsAsync_WhenPaginationFails_ShouldPropagateError() .ReturnsAsync(Result>.Failure(StatusCodes.Status400BadRequest, "Invalid page number")); var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, - dateTimeServiceMock.Object, paginationServiceMock.Object); + dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); // Act var result = await sut.GetEventsAsync(page, pageSize); @@ -391,6 +419,7 @@ public async Task GetEventsPaginationDetailsAsync_WhenSuccessful_ShouldReturnPag var addressServiceMock = new Mock(); var dateTimeServiceMock = new Mock(); var paginationServiceMock = new Mock(); + var categoryRepositoryMock = new Mock(); var eventsQueryable = events.AsQueryable(); eventRepositoryMock.Setup(p => p.GetEvents()).Returns(eventsQueryable); @@ -401,7 +430,7 @@ public async Task GetEventsPaginationDetailsAsync_WhenSuccessful_ShouldReturnPag .ReturnsAsync(Result.Success(paginationDetails)); var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, - dateTimeServiceMock.Object, paginationServiceMock.Object); + dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); // Act var result = await sut.GetEventsPaginationDetailsAsync(pageSize); @@ -428,6 +457,7 @@ public async Task GetEventsPaginationDetailsAsync_WhenFails_ShouldReturnError() var addressServiceMock = new Mock(); var dateTimeServiceMock = new Mock(); var paginationServiceMock = new Mock(); + var categoryRepositoryMock = new Mock(); var eventsQueryable = events.AsQueryable(); eventRepositoryMock.Setup(p => p.GetEvents()).Returns(eventsQueryable); @@ -437,7 +467,7 @@ public async Task GetEventsPaginationDetailsAsync_WhenFails_ShouldReturnError() .ReturnsAsync(Result.Failure(StatusCodes.Status400BadRequest, "Invalid page size")); var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, - dateTimeServiceMock.Object, paginationServiceMock.Object); + dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); // Act var result = await sut.GetEventsPaginationDetailsAsync(pageSize); diff --git a/TickAPI/TickAPI/Categories/DTOs/Request/CreateEventCategoryDto.cs b/TickAPI/TickAPI/Categories/DTOs/Request/CreateEventCategoryDto.cs new file mode 100644 index 0000000..8e696d7 --- /dev/null +++ b/TickAPI/TickAPI/Categories/DTOs/Request/CreateEventCategoryDto.cs @@ -0,0 +1,6 @@ +namespace TickAPI.Categories.DTOs.Request; + +public record CreateEventCategoryDto +( + string CategoryName +); \ No newline at end of file diff --git a/TickAPI/TickAPI/Events/Abstractions/IEventService.cs b/TickAPI/TickAPI/Events/Abstractions/IEventService.cs index 8afbaad..b2267ba 100644 --- a/TickAPI/TickAPI/Events/Abstractions/IEventService.cs +++ b/TickAPI/TickAPI/Events/Abstractions/IEventService.cs @@ -1,5 +1,6 @@ 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; @@ -10,7 +11,8 @@ namespace TickAPI.Events.Abstractions; public interface IEventService { public Task> CreateNewEventAsync(string name, string description, DateTime startDate, - DateTime endDate, uint? minimumAge, CreateAddressDto createAddress, EventStatus eventStatus, string organizerEmail); + DateTime endDate, uint? minimumAge, CreateAddressDto createAddress, List categories + ,EventStatus eventStatus, string organizerEmail); public Task>> GetOrganizerEventsAsync(Organizer organizer, int page, int pageSize); public Task> GetOrganizerEventsPaginationDetailsAsync(Organizer organizer, int pageSize); public Task>> GetEventsAsync(int page, int pageSize); diff --git a/TickAPI/TickAPI/Events/Controllers/EventController.cs b/TickAPI/TickAPI/Events/Controllers/EventController.cs index 5ea6f4e..f368926 100644 --- a/TickAPI/TickAPI/Events/Controllers/EventController.cs +++ b/TickAPI/TickAPI/Events/Controllers/EventController.cs @@ -38,7 +38,9 @@ public async Task> 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.EventStatus, email); if (newEventResult.IsError) return StatusCode(newEventResult.StatusCode, newEventResult.ErrorMsg); diff --git a/TickAPI/TickAPI/Events/DTOs/Request/CreateEventDto.cs b/TickAPI/TickAPI/Events/DTOs/Request/CreateEventDto.cs index 1078587..01bb591 100644 --- a/TickAPI/TickAPI/Events/DTOs/Request/CreateEventDto.cs +++ b/TickAPI/TickAPI/Events/DTOs/Request/CreateEventDto.cs @@ -1,15 +1,16 @@ using TickAPI.Events.Models; using TickAPI.Addresses.DTOs.Request; +using TickAPI.Categories.DTOs.Request; namespace TickAPI.Events.DTOs.Request; -public record CreateEventDto -( +public record CreateEventDto( string Name, string Description, DateTime StartDate, DateTime EndDate, uint? MinimumAge, + List Categories, EventStatus EventStatus, CreateAddressDto CreateAddress ); \ No newline at end of file diff --git a/TickAPI/TickAPI/Events/Services/EventService.cs b/TickAPI/TickAPI/Events/Services/EventService.cs index 6ac130c..30c7d8b 100644 --- a/TickAPI/TickAPI/Events/Services/EventService.cs +++ b/TickAPI/TickAPI/Events/Services/EventService.cs @@ -2,6 +2,9 @@ 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; @@ -19,17 +22,21 @@ public class EventService : IEventService private readonly IAddressService _addressService; private readonly IDateTimeService _dateTimeService; private readonly IPaginationService _paginationService; + private readonly ICategoryRepository _categoryRepository; - public EventService(IEventRepository eventRepository, IOrganizerService organizerService, IAddressService addressService, IDateTimeService dateTimeService, IPaginationService paginationService) + public EventService(IEventRepository eventRepository, IOrganizerService organizerService, IAddressService addressService, IDateTimeService dateTimeService, IPaginationService paginationService, ICategoryRepository categoryRepository) { _eventRepository = eventRepository; _organizerService = organizerService; _addressService = addressService; _dateTimeService = dateTimeService; _paginationService = paginationService; + _categoryRepository = categoryRepository; } - public async Task> CreateNewEventAsync(string name, string description, DateTime startDate, DateTime endDate, uint? minimumAge, CreateAddressDto createAddress, EventStatus eventStatus, string organizerEmail) + public async Task> CreateNewEventAsync(string name, string description, DateTime startDate, DateTime endDate, + uint? minimumAge, CreateAddressDto createAddress, List categories, + EventStatus eventStatus, string organizerEmail) { var organizerResult = await _organizerService.GetOrganizerByEmailAsync(organizerEmail); if (!organizerResult.IsSuccess) @@ -44,6 +51,16 @@ public async Task> CreateNewEventAsync(string name, string descri var address = await _addressService.GetOrCreateAddressAsync(createAddress); + + var categoriesConverted = new List(); + + foreach (var c in categories) + { + categoriesConverted.Add(new Category + { + Name = c.CategoryName + }); + } var @event = new Event { @@ -53,6 +70,7 @@ public async Task> CreateNewEventAsync(string name, string descri EndDate = endDate, MinimumAge = minimumAge, Address = address.Value!, + Categories = categoriesConverted, Organizer = organizerResult.Value!, EventStatus = eventStatus }; From 5658a19fb43ca4f9b7b45c8a8a7b0f616fbab41e Mon Sep 17 00:00:00 2001 From: kubapoke Date: Mon, 14 Apr 2025 14:46:36 +0200 Subject: [PATCH 09/33] changed endpoint names --- .../Categories/Controllers/CategoryController.cs | 5 ++--- TickAPI/TickAPI/Events/Controllers/EventController.cs | 10 +++++----- .../Organizers/Controllers/OrganizerController.cs | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/TickAPI/TickAPI/Categories/Controllers/CategoryController.cs b/TickAPI/TickAPI/Categories/Controllers/CategoryController.cs index e7d7469..7ec4ea6 100644 --- a/TickAPI/TickAPI/Categories/Controllers/CategoryController.cs +++ b/TickAPI/TickAPI/Categories/Controllers/CategoryController.cs @@ -10,7 +10,6 @@ namespace TickAPI.Categories.Controllers; [ApiController] [Route("api/[controller]")] - public class CategoryController : Controller { private readonly ICategoryService _categoryService; @@ -21,7 +20,7 @@ public CategoryController(ICategoryService categoryService) } [AuthorizeWithPolicy(AuthPolicies.VerifiedUserPolicy)] - [HttpGet("get-categories")] + [HttpGet("categories")] public async Task>> GetCategories([FromQuery] int pageSize, [FromQuery] int page) { var res = await _categoryService.GetCategoriesResponsesAsync(pageSize, page); @@ -33,7 +32,7 @@ public async Task>> GetCatego } // TODO: Add appropriate policy verification (admin, maybe also organizer?) - [HttpPost("create-category")] + [HttpPost("category")] public async Task CreateCategory([FromBody] CreateCategoryDto request) { var newCategoryResult = await _categoryService.CreateNewCategoryAsync(request.Name); diff --git a/TickAPI/TickAPI/Events/Controllers/EventController.cs b/TickAPI/TickAPI/Events/Controllers/EventController.cs index 5ea6f4e..09b2e65 100644 --- a/TickAPI/TickAPI/Events/Controllers/EventController.cs +++ b/TickAPI/TickAPI/Events/Controllers/EventController.cs @@ -28,7 +28,7 @@ public EventController(IEventService eventService, IClaimsService claimsService, } [AuthorizeWithPolicy(AuthPolicies.VerifiedOrganizerPolicy)] - [HttpPost("create-event")] + [HttpPost("event")] public async Task> CreateEvent([FromBody] CreateEventDto request) { var emailResult = _claimsService.GetEmailFromClaims(User.Claims); @@ -47,7 +47,7 @@ public async Task> CreateEvent([FromBody] C } [AuthorizeWithPolicy(AuthPolicies.VerifiedOrganizerPolicy)] - [HttpGet("get-organizer-events")] + [HttpGet("organizer-events")] public async Task>> GetOrganizerEvents([FromQuery] int pageSize, [FromQuery] int page) { var emailResult = _claimsService.GetEmailFromClaims(User.Claims); @@ -74,7 +74,7 @@ public async Task>> GetOrganizer } [AuthorizeWithPolicy(AuthPolicies.VerifiedOrganizerPolicy)] - [HttpGet("get-organizer-events-pagination-details")] + [HttpGet("organizer-events-pagination-details")] public async Task> GetOrganizerEventsPaginationDetails([FromQuery] int pageSize) { var emailResult = _claimsService.GetEmailFromClaims(User.Claims); @@ -101,7 +101,7 @@ public async Task> GetOrganizerEventsPaginationD } [AuthorizeWithPolicy(AuthPolicies.CustomerPolicy)] - [HttpGet("get-events")] + [HttpGet("events")] public async Task>> GetEvents([FromQuery] int pageSize, [FromQuery] int page) { var paginatedDataResult = await _eventService.GetEventsAsync(page, pageSize); @@ -113,7 +113,7 @@ public async Task>> GetEvents([F } [AuthorizeWithPolicy(AuthPolicies.CustomerPolicy)] - [HttpGet("get-events-pagination-details")] + [HttpGet("events-pagination-details")] public async Task> GetEventsPaginationDetails([FromQuery] int pageSize) { var paginationDetailsResult = await _eventService.GetEventsPaginationDetailsAsync(pageSize); diff --git a/TickAPI/TickAPI/Organizers/Controllers/OrganizerController.cs b/TickAPI/TickAPI/Organizers/Controllers/OrganizerController.cs index 4643556..a4644d6 100644 --- a/TickAPI/TickAPI/Organizers/Controllers/OrganizerController.cs +++ b/TickAPI/TickAPI/Organizers/Controllers/OrganizerController.cs @@ -62,7 +62,7 @@ public async Task> GoogleLogin([Fr } [AuthorizeWithPolicy(AuthPolicies.NewOrganizerPolicy)] - [HttpPost("create-organizer")] + [HttpPost("organizer")] public async Task> CreateOrganizer([FromBody] CreateOrganizerDto request) { var emailResult = _claimsService.GetEmailFromClaims(User.Claims); From 446bae3f182dc37c134c59149e77b96dde700d8a Mon Sep 17 00:00:00 2001 From: kTrzcinskii Date: Mon, 14 Apr 2025 23:57:16 +0200 Subject: [PATCH 10/33] Fixes after code review --- TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs | 7 ++++--- TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs | 2 +- TickAPI/TickAPI/Events/Services/EventFilter.cs | 8 ++++---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs b/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs index 761a72a..a630b39 100644 --- a/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs +++ b/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs @@ -255,7 +255,8 @@ public void FilterByMaxPrice_ShouldReturnMatchingEvents() var result = eventFilter.GetEvents().ToList(); // Assert - Assert.Single(result); + Assert.Equal(2, result.Count); + Assert.Contains(events[0], result); Assert.Contains(events[1], result); } @@ -277,14 +278,14 @@ public void FilterByMinAge_ShouldReturnMatchingEvents() } [Fact] - public void FilterByMaxAge_ShouldReturnMatchingEvents() + public void FilterByMaxMinimumAge_ShouldReturnMatchingEvents() { // Arrange var events = GetTestEvents(); // Act var eventFilter = new EventFilter(events.AsQueryable()); - eventFilter.FilterByMaxAge(18); + eventFilter.FilterByMaxMinimumAge(18); var result = eventFilter.GetEvents().ToList(); // Assert diff --git a/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs b/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs index 369b10d..a4aa175 100644 --- a/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs +++ b/TickAPI/TickAPI/Events/Abstractions/IEventFilter.cs @@ -16,7 +16,7 @@ public interface IEventFilter void FilterByMinPrice(decimal minPrice); void FilterByMaxPrice(decimal maxPrice); void FilterByMinAge(uint minAge); - void FilterByMaxAge(uint maxAge); + void FilterByMaxMinimumAge(uint maxMinimumAge); void FilterByAddressCountry(string country); void FilterByAddressCity(string city); void FilterByAddressStreet(string street, uint? houseNumber, uint? flatNumber); diff --git a/TickAPI/TickAPI/Events/Services/EventFilter.cs b/TickAPI/TickAPI/Events/Services/EventFilter.cs index 6e55c9c..f96ed48 100644 --- a/TickAPI/TickAPI/Events/Services/EventFilter.cs +++ b/TickAPI/TickAPI/Events/Services/EventFilter.cs @@ -59,12 +59,12 @@ public void FilterByMaxEndDate(DateTime endDate) public void FilterByMinPrice(decimal minPrice) { - _events = _events.Where(e => e.TicketTypes.All(t => t.Price >= minPrice)); + _events = _events.Where(e => e.TicketTypes.Any(t => t.Price >= minPrice)); } public void FilterByMaxPrice(decimal maxPrice) { - _events = _events.Where(e => e.TicketTypes.All(t => t.Price <= maxPrice)); + _events = _events.Where(e => e.TicketTypes.Any(t => t.Price <= maxPrice)); } public void FilterByMinAge(uint minAge) @@ -72,9 +72,9 @@ public void FilterByMinAge(uint minAge) _events = _events.Where(e => e.MinimumAge >= minAge); } - public void FilterByMaxAge(uint maxAge) + public void FilterByMaxMinimumAge(uint maxMinimumAge) { - _events = _events.Where(e => e.MinimumAge <= maxAge); + _events = _events.Where(e => e.MinimumAge <= maxMinimumAge); } public void FilterByAddressCountry(string country) From 027aec05366468b6238a10995d83ee84ed449563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Tue, 15 Apr 2025 11:33:52 +0200 Subject: [PATCH 11/33] Check if categories exist --- .../TickAPI/Categories/Abstractions/ICategoryRepository.cs | 2 ++ .../Categories/DTOs/{ => Request}/CreateCategoryDto.cs | 0 .../TickAPI/Categories/Respositories/CategoryRepository.cs | 6 ++++++ TickAPI/TickAPI/Events/Services/EventService.cs | 6 ++++++ 4 files changed, 14 insertions(+) rename TickAPI/TickAPI/Categories/DTOs/{ => Request}/CreateCategoryDto.cs (100%) diff --git a/TickAPI/TickAPI/Categories/Abstractions/ICategoryRepository.cs b/TickAPI/TickAPI/Categories/Abstractions/ICategoryRepository.cs index c7d1fc3..9e6e598 100644 --- a/TickAPI/TickAPI/Categories/Abstractions/ICategoryRepository.cs +++ b/TickAPI/TickAPI/Categories/Abstractions/ICategoryRepository.cs @@ -8,4 +8,6 @@ public interface ICategoryRepository public IQueryable GetCategories(); public Task> GetCategoryByNameAsync(string categoryName); public Task AddNewCategoryAsync(Category category); + + public Task CheckIfCategoriesExistAsync(List categories); } \ No newline at end of file diff --git a/TickAPI/TickAPI/Categories/DTOs/CreateCategoryDto.cs b/TickAPI/TickAPI/Categories/DTOs/Request/CreateCategoryDto.cs similarity index 100% rename from TickAPI/TickAPI/Categories/DTOs/CreateCategoryDto.cs rename to TickAPI/TickAPI/Categories/DTOs/Request/CreateCategoryDto.cs diff --git a/TickAPI/TickAPI/Categories/Respositories/CategoryRepository.cs b/TickAPI/TickAPI/Categories/Respositories/CategoryRepository.cs index e1dcdb2..4360419 100644 --- a/TickAPI/TickAPI/Categories/Respositories/CategoryRepository.cs +++ b/TickAPI/TickAPI/Categories/Respositories/CategoryRepository.cs @@ -31,6 +31,12 @@ public async Task> GetCategoryByNameAsync(string categoryName) return Result.Success(category); } + public async Task CheckIfCategoriesExistAsync(List categories) + { + var dbCategories = await _tickApiDbContext.Categories.ToListAsync(); + return categories.All(c => dbCategories.Contains(c)); + } + public async Task AddNewCategoryAsync(Category category) { _tickApiDbContext.Categories.Add(category); diff --git a/TickAPI/TickAPI/Events/Services/EventService.cs b/TickAPI/TickAPI/Events/Services/EventService.cs index 30c7d8b..837da66 100644 --- a/TickAPI/TickAPI/Events/Services/EventService.cs +++ b/TickAPI/TickAPI/Events/Services/EventService.cs @@ -61,6 +61,12 @@ public async Task> CreateNewEventAsync(string name, string descri Name = c.CategoryName }); } + + var categoriesExist = await _categoryRepository.CheckIfCategoriesExistAsync(categoriesConverted); + if (!categoriesExist) + { + return Result.Failure(StatusCodes.Status403Forbidden, "Category does not exist"); + } var @event = new Event { From e55616bb6daf4eff15085b04477696a3325651d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Tue, 15 Apr 2025 12:45:23 +0200 Subject: [PATCH 12/33] Handle non existing categories --- TickAPI/TickAPI/Categories/Respositories/CategoryRepository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TickAPI/TickAPI/Categories/Respositories/CategoryRepository.cs b/TickAPI/TickAPI/Categories/Respositories/CategoryRepository.cs index 4360419..0f920ac 100644 --- a/TickAPI/TickAPI/Categories/Respositories/CategoryRepository.cs +++ b/TickAPI/TickAPI/Categories/Respositories/CategoryRepository.cs @@ -34,7 +34,7 @@ public async Task> GetCategoryByNameAsync(string categoryName) public async Task CheckIfCategoriesExistAsync(List categories) { var dbCategories = await _tickApiDbContext.Categories.ToListAsync(); - return categories.All(c => dbCategories.Contains(c)); + return categories.All(c => dbCategories.Any(cdb => cdb.Name == c.Name)); } public async Task AddNewCategoryAsync(Category category) From c1a6b9965f2f6449b5f5a7293381aed8aba98e50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Thu, 17 Apr 2025 12:46:00 +0200 Subject: [PATCH 13/33] Add ticket types to created events and tests --- .../Controllers/EventControllerTests.cs | 17 ++- .../Events/Services/EventServiceTests.cs | 123 +++++++++++++++++- .../Events/Abstractions/IEventService.cs | 3 +- .../Events/Controllers/EventController.cs | 2 +- .../Events/DTOs/Request/CreateEventDto.cs | 2 + .../TickAPI/Events/Services/EventService.cs | 31 ++++- .../Request/CreateAddressTicketTypeDto.cs | 9 ++ 7 files changed, 175 insertions(+), 12 deletions(-) create mode 100644 TickAPI/TickAPI/TicketTypes/DTOs/Request/CreateAddressTicketTypeDto.cs diff --git a/TickAPI/TickAPI.Tests/Events/Controllers/EventControllerTests.cs b/TickAPI/TickAPI.Tests/Events/Controllers/EventControllerTests.cs index c1f2947..c0789fa 100644 --- a/TickAPI/TickAPI.Tests/Events/Controllers/EventControllerTests.cs +++ b/TickAPI/TickAPI.Tests/Events/Controllers/EventControllerTests.cs @@ -14,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; @@ -36,12 +37,17 @@ public async Task CreateEvent_WhenDataIsValid_ShouldReturnSuccess() new CreateEventCategoryDto("concert"), new CreateEventCategoryDto("bear metal") ]; + List 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, categories, eventStatus, createAddress); + CreateEventDto eventDto = new CreateEventDto(name, description, startDate, endDate, minimumAge, categories, ticketTypes, eventStatus, createAddress); var eventServiceMock = new Mock(); eventServiceMock - .Setup(m => m.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, categories ,eventStatus, email)) + .Setup(m => m.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, categories , ticketTypes, eventStatus, email)) .ReturnsAsync(Result.Success(new Event())); var claims = new List @@ -91,6 +97,11 @@ public async Task CreateEvent_WhenMissingEmailClaims_ShouldReturnBadRequest() new CreateEventCategoryDto("concert"), new CreateEventCategoryDto("bear metal") ]; + List 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(); @@ -110,7 +121,7 @@ public async Task CreateEvent_WhenMissingEmailClaims_ShouldReturnBadRequest() }; // act - var res = await sut.CreateEvent(new CreateEventDto(name, description, startDate, endDate, minimumAge, categories, eventStatus, createAddress)); + var res = await sut.CreateEvent(new CreateEventDto(name, description, startDate, endDate, minimumAge, categories, ticketTypes, eventStatus, createAddress)); // Assert var result = Assert.IsType>(res); diff --git a/TickAPI/TickAPI.Tests/Events/Services/EventServiceTests.cs b/TickAPI/TickAPI.Tests/Events/Services/EventServiceTests.cs index a14f429..78d2c7c 100644 --- a/TickAPI/TickAPI.Tests/Events/Services/EventServiceTests.cs +++ b/TickAPI/TickAPI.Tests/Events/Services/EventServiceTests.cs @@ -8,6 +8,7 @@ using TickAPI.Common.Pagination.Responses; using TickAPI.Categories.Abstractions; using TickAPI.Categories.DTOs.Request; +using TickAPI.Categories.Models; using TickAPI.Events.Models; using TickAPI.Organizers.Abstractions; using TickAPI.Organizers.Models; @@ -15,6 +16,8 @@ using TickAPI.Common.Time.Abstractions; using TickAPI.Events.DTOs.Response; using TickAPI.Events.Services; +using TickAPI.TicketTypes.DTOs.Request; +using TickAPI.TicketTypes.Models; namespace TickAPI.Tests.Events.Services; @@ -38,6 +41,42 @@ public async Task CreateNewEventAsync_WhenEventDataIsValid_ShouldReturnNewEvent( new CreateEventCategoryDto("concert"), new CreateEventCategoryDto("bear metal") ]; + List expectedCategories = + [ + new Category + { + Name = "concert", + }, + new Category + { + Name = "bear metal", + } + + ]; + List 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)), + ]; + List expectedTicketTypes = + [ + new TicketType + { + Description = "normal", + MaxCount = 100, + Price = 50.9m, + Currency = "zł", + AvailableFrom = new DateTime(2025, 5, 1) + }, + new TicketType + { + Description = "V.I.P", + MaxCount = 10, + Price = 500.9m, + Currency = "zł", + AvailableFrom = new DateTime(2025, 5, 10) + }, + ]; CreateAddressDto createAddress = new CreateAddressDto("United States", "New York", "Main st", 20, null, "00-000"); var eventRepositoryMock = new Mock(); @@ -66,12 +105,13 @@ public async Task CreateNewEventAsync_WhenEventDataIsValid_ShouldReturnNewEvent( dateTimeServiceMock.Setup(m => m.GetCurrentDateTime()).Returns(new DateTime(2003, 7, 11)); var categoryRepositoryMock = new Mock(); + categoryRepositoryMock.Setup(c => c.CheckIfCategoriesExistAsync(It.IsAny>())).Returns(Task.FromResult(true)); var paginationServiceMock = new Mock(); var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); // act - var result = await sut.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, categories, eventStatus, organizerEmail); + var result = await sut.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, categories, ticketTypes, eventStatus, organizerEmail); // Assert Assert.True(result.IsSuccess); @@ -82,6 +122,22 @@ public async Task CreateNewEventAsync_WhenEventDataIsValid_ShouldReturnNewEvent( Assert.Equal(eventStatus, result.Value!.EventStatus); Assert.Equal(id, result.Value!.Id); Assert.Equal(organizerEmail, result.Value!.Organizer.Email); + Assert.Equal(expectedCategories.Count, result.Value!.Categories.Count); + foreach (var expectedCategory in expectedCategories) + { + Assert.Contains(result.Value!.Categories, actualCategory => + actualCategory.Name == expectedCategory.Name); + } + Assert.Equal(expectedTicketTypes.Count, result.Value!.TicketTypes.Count); + foreach (var expectedTicketType in expectedTicketTypes) + { + Assert.Contains(result.Value!.TicketTypes, actualTicketType => + actualTicketType.Description == expectedTicketType.Description && + actualTicketType.MaxCount == expectedTicketType.MaxCount && + actualTicketType.Price == expectedTicketType.Price && + actualTicketType.Currency == expectedTicketType.Currency && + actualTicketType.AvailableFrom == expectedTicketType.AvailableFrom); + } } [Fact] @@ -101,6 +157,11 @@ public async Task CreateNewEventAsync_WhenEndDateIsBeforeStartDate_ShouldReturnB new CreateEventCategoryDto("concert"), new CreateEventCategoryDto("bear metal") ]; + List 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 eventRepositoryMock = new Mock(); @@ -122,7 +183,7 @@ public async Task CreateNewEventAsync_WhenEndDateIsBeforeStartDate_ShouldReturnB var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); - var res = await sut.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, categories, eventStatus, organizerEmail); + var res = await sut.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, categories, ticketTypes, eventStatus, organizerEmail); // Assert Assert.False(res.IsSuccess); @@ -130,6 +191,57 @@ public async Task CreateNewEventAsync_WhenEndDateIsBeforeStartDate_ShouldReturnB Assert.Equal("End date should be after start date", res.ErrorMsg); } + [Fact] + public async Task CreateNewEventAsync_WhenTicketTypeAvailabilityIsAfterEventsEnd_ShouldReturnBadRequest() + { + // Arrange + string name = "Concert"; + string description = "Description of a concert"; + DateTime startDate = new DateTime(2025, 5, 1); + DateTime endDate = new DateTime(2025, 6, 1); + uint? minimumAge = 18; + string organizerEmail = "123@mail.com"; + EventStatus eventStatus = EventStatus.TicketsAvailable; + Guid id = Guid.NewGuid(); + List categories = + [ + new CreateEventCategoryDto("concert"), + new CreateEventCategoryDto("bear metal") + ]; + List 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, 6, 10)), + ]; + CreateAddressDto createAddress = new CreateAddressDto("United States", "New York", "Main st", 20, null, "00-000"); + + var eventRepositoryMock = new Mock(); + + var organizerServiceMock = new Mock(); + organizerServiceMock + .Setup(m => m.GetOrganizerByEmailAsync(organizerEmail)) + .ReturnsAsync(Result.Success(new Organizer { Email = organizerEmail, IsVerified = true })); + + var addressServiceMock = new Mock(); + + var dateTimeServiceMock = new Mock(); + dateTimeServiceMock.Setup(m => m.GetCurrentDateTime()).Returns(new DateTime(2025, 4, 11)); + + var categoryRepositoryMock = new Mock(); + + // act + var paginationServiceMock = new Mock(); + + var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); + + var res = await sut.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, categories, ticketTypes, eventStatus, organizerEmail); + + // Assert + Assert.False(res.IsSuccess); + Assert.Equal(StatusCodes.Status400BadRequest, res.StatusCode); + Assert.Equal("Tickets can't be available after the event is over", res.ErrorMsg); + } + [Fact] public async Task CreateNewEventAsync_WhenStartDateIsBeforeNow_ShouldReturnBadRequest() { @@ -147,6 +259,11 @@ public async Task CreateNewEventAsync_WhenStartDateIsBeforeNow_ShouldReturnBadRe new CreateEventCategoryDto("concert"), new CreateEventCategoryDto("bear metal") ]; + List 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 eventRepositoryMock = new Mock(); @@ -168,7 +285,7 @@ public async Task CreateNewEventAsync_WhenStartDateIsBeforeNow_ShouldReturnBadRe var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); - var res = await sut.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, categories, eventStatus, organizerEmail); + var res = await sut.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, categories, ticketTypes, eventStatus, organizerEmail); // Assert Assert.False(res.IsSuccess); diff --git a/TickAPI/TickAPI/Events/Abstractions/IEventService.cs b/TickAPI/TickAPI/Events/Abstractions/IEventService.cs index b2267ba..465defd 100644 --- a/TickAPI/TickAPI/Events/Abstractions/IEventService.cs +++ b/TickAPI/TickAPI/Events/Abstractions/IEventService.cs @@ -5,6 +5,7 @@ using TickAPI.Common.Results.Generic; using TickAPI.Events.DTOs.Response; using TickAPI.Organizers.Models; +using TickAPI.TicketTypes.DTOs.Request; namespace TickAPI.Events.Abstractions; @@ -12,7 +13,7 @@ public interface IEventService { public Task> CreateNewEventAsync(string name, string description, DateTime startDate, DateTime endDate, uint? minimumAge, CreateAddressDto createAddress, List categories - ,EventStatus eventStatus, string organizerEmail); + , List ticketTypes,EventStatus eventStatus, string organizerEmail); public Task>> GetOrganizerEventsAsync(Organizer organizer, int page, int pageSize); public Task> GetOrganizerEventsPaginationDetailsAsync(Organizer organizer, int pageSize); public Task>> GetEventsAsync(int page, int pageSize); diff --git a/TickAPI/TickAPI/Events/Controllers/EventController.cs b/TickAPI/TickAPI/Events/Controllers/EventController.cs index f368926..27594f7 100644 --- a/TickAPI/TickAPI/Events/Controllers/EventController.cs +++ b/TickAPI/TickAPI/Events/Controllers/EventController.cs @@ -40,7 +40,7 @@ public async Task> CreateEvent([FromBody] C var newEventResult = await _eventService.CreateNewEventAsync(request.Name, request.Description, request.StartDate, request.EndDate, request.MinimumAge, request.CreateAddress, request.Categories - ,request.EventStatus, email); + , request.TicketTypes ,request.EventStatus, email); if (newEventResult.IsError) return StatusCode(newEventResult.StatusCode, newEventResult.ErrorMsg); diff --git a/TickAPI/TickAPI/Events/DTOs/Request/CreateEventDto.cs b/TickAPI/TickAPI/Events/DTOs/Request/CreateEventDto.cs index 01bb591..5b6f447 100644 --- a/TickAPI/TickAPI/Events/DTOs/Request/CreateEventDto.cs +++ b/TickAPI/TickAPI/Events/DTOs/Request/CreateEventDto.cs @@ -1,6 +1,7 @@ using TickAPI.Events.Models; using TickAPI.Addresses.DTOs.Request; using TickAPI.Categories.DTOs.Request; +using TickAPI.TicketTypes.DTOs.Request; namespace TickAPI.Events.DTOs.Request; @@ -11,6 +12,7 @@ public record CreateEventDto( DateTime EndDate, uint? MinimumAge, List Categories, + List TicketTypes, EventStatus EventStatus, CreateAddressDto CreateAddress ); \ No newline at end of file diff --git a/TickAPI/TickAPI/Events/Services/EventService.cs b/TickAPI/TickAPI/Events/Services/EventService.cs index 837da66..e258c92 100644 --- a/TickAPI/TickAPI/Events/Services/EventService.cs +++ b/TickAPI/TickAPI/Events/Services/EventService.cs @@ -12,6 +12,8 @@ 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; @@ -35,7 +37,7 @@ public EventService(IEventRepository eventRepository, IOrganizerService organize } public async Task> CreateNewEventAsync(string name, string description, DateTime startDate, DateTime endDate, - uint? minimumAge, CreateAddressDto createAddress, List categories, + uint? minimumAge, CreateAddressDto createAddress, List categories, List ticketTypes, EventStatus eventStatus, string organizerEmail) { var organizerResult = await _organizerService.GetOrganizerByEmailAsync(organizerEmail); @@ -48,7 +50,14 @@ public async Task> CreateNewEventAsync(string name, string descri if (startDate < _dateTimeService.GetCurrentDateTime()) return Result.Failure(StatusCodes.Status400BadRequest, "Start date is in the past"); - + + foreach (var t in ticketTypes) + { + if (t.AvailableFrom > endDate) + { + return Result.Failure(StatusCodes.Status400BadRequest, "Tickets can't be available after the event is over"); + } + } var address = await _addressService.GetOrCreateAddressAsync(createAddress); @@ -67,6 +76,19 @@ public async Task> CreateNewEventAsync(string name, string descri { return Result.Failure(StatusCodes.Status403Forbidden, "Category does not exist"); } + + var ticketTypesConverted = new List(); + foreach (var t in ticketTypes) + { + ticketTypesConverted.Add(new TicketType + { + Description = t.Description, + AvailableFrom = t.AvailableFrom, + Currency = t.Currency, + MaxCount = t.MaxCount, + Price = t.Price, + }); + } var @event = new Event { @@ -78,7 +100,8 @@ public async Task> CreateNewEventAsync(string name, string descri Address = address.Value!, Categories = categoriesConverted, Organizer = organizerResult.Value!, - EventStatus = eventStatus + EventStatus = eventStatus, + TicketTypes = ticketTypesConverted, }; await _eventRepository.AddNewEventAsync(@event); return Result.Success(@event); @@ -123,7 +146,7 @@ private async Task>> 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(); 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); } diff --git a/TickAPI/TickAPI/TicketTypes/DTOs/Request/CreateAddressTicketTypeDto.cs b/TickAPI/TickAPI/TicketTypes/DTOs/Request/CreateAddressTicketTypeDto.cs new file mode 100644 index 0000000..96a002c --- /dev/null +++ b/TickAPI/TickAPI/TicketTypes/DTOs/Request/CreateAddressTicketTypeDto.cs @@ -0,0 +1,9 @@ +namespace TickAPI.TicketTypes.DTOs.Request; + +public record CreateEventTicketTypeDto( + string Description, + uint MaxCount, + decimal Price, + string Currency, + DateTime AvailableFrom + ); \ No newline at end of file From c6e4cd64d91d77f95e0697a596e78cd6ee223478 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Thu, 17 Apr 2025 20:46:49 +0200 Subject: [PATCH 14/33] Add or update the Azure App Service build and deployment workflow config --- ...twithcategoriesandtickettyped_resellio.yml | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 .github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml diff --git a/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml b/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml new file mode 100644 index 0000000..7376649 --- /dev/null +++ b/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml @@ -0,0 +1,68 @@ +# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy +# More GitHub Actions for Azure: https://github.com/Azure/actions + +name: Build and deploy ASP.Net Core app to Azure Web App - resellio + +on: + push: + branches: + - feat/CreateEventWithCategoriesAndTicketTyped + workflow_dispatch: + +jobs: + build: + runs-on: windows-latest + permissions: + contents: read #This is required for actions/checkout + + steps: + - uses: actions/checkout@v4 + + - name: Set up .NET Core + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '6.0.x' + + - name: Build with dotnet + run: dotnet build --configuration Release + + - name: dotnet publish + run: dotnet publish -c Release -o "${{env.DOTNET_ROOT}}/myapp" + + - name: Upload artifact for deployment job + uses: actions/upload-artifact@v4 + with: + name: .net-app + path: ${{env.DOTNET_ROOT}}/myapp + + deploy: + runs-on: windows-latest + needs: build + environment: + name: 'Production' + url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} + permissions: + id-token: write #This is required for requesting the JWT + contents: read #This is required for actions/checkout + + steps: + - name: Download artifact from build job + uses: actions/download-artifact@v4 + with: + name: .net-app + + - name: Login to Azure + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_0D0336DEAF734574B53DD4A5D2E898A0 }} + tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_800D316A4C714278AB484F215A6303F0 }} + subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_E2CF62C6C3CB48B0AFF01965324F5D3A }} + + - name: Deploy to Azure Web App + id: deploy-to-webapp + uses: azure/webapps-deploy@v3 + with: + app-name: 'resellio' + slot-name: 'Production' + package: . + \ No newline at end of file From 49cf8dd456d9079dd152cb6606e3b79dc734015a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Thu, 17 Apr 2025 20:53:34 +0200 Subject: [PATCH 15/33] Add or update the Azure App Service build and deployment workflow config --- ...eat-createeventwithcategoriesandtickettyped_resellio.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml b/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml index 7376649..39af33e 100644 --- a/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml +++ b/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml @@ -54,9 +54,9 @@ jobs: - name: Login to Azure uses: azure/login@v2 with: - client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_0D0336DEAF734574B53DD4A5D2E898A0 }} - tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_800D316A4C714278AB484F215A6303F0 }} - subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_E2CF62C6C3CB48B0AFF01965324F5D3A }} + client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_1E79017744574753935FA54217321744 }} + tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_45CB50561E614FBB9482DD79882CEA2A }} + subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_036603283F034371B4B2C33640B40CEB }} - name: Deploy to Azure Web App id: deploy-to-webapp From 15ae96aa337b5559e6aebd4e16e527161cfb902d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Thu, 17 Apr 2025 20:57:56 +0200 Subject: [PATCH 16/33] Update feat-createeventwithcategoriesandtickettyped_resellio.yml --- ...twithcategoriesandtickettyped_resellio.yml | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml b/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml index 39af33e..f54eca3 100644 --- a/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml +++ b/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml @@ -27,36 +27,36 @@ jobs: run: dotnet build --configuration Release - name: dotnet publish - run: dotnet publish -c Release -o "${{env.DOTNET_ROOT}}/myapp" + run: dotnet publish -c Release -o "${{env.DOTNET_ROOT}}/TickApi" - name: Upload artifact for deployment job uses: actions/upload-artifact@v4 with: name: .net-app - path: ${{env.DOTNET_ROOT}}/myapp + path: ${{env.DOTNET_ROOT}}/TickApi deploy: runs-on: windows-latest needs: build - environment: - name: 'Production' + environment: + name: 'Production' url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} - permissions: - id-token: write #This is required for requesting the JWT - contents: read #This is required for actions/checkout + permissions: + id-token: write #This is required for requesting the JWT + contents: read #This is required for actions/checkout steps: - name: Download artifact from build job uses: actions/download-artifact@v4 with: name: .net-app - - - name: Login to Azure - uses: azure/login@v2 - with: - client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_1E79017744574753935FA54217321744 }} - tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_45CB50561E614FBB9482DD79882CEA2A }} - subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_036603283F034371B4B2C33640B40CEB }} + + - name: Login to Azure + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_1E79017744574753935FA54217321744 }} + tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_45CB50561E614FBB9482DD79882CEA2A }} + subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_036603283F034371B4B2C33640B40CEB }} - name: Deploy to Azure Web App id: deploy-to-webapp @@ -65,4 +65,4 @@ jobs: app-name: 'resellio' slot-name: 'Production' package: . - \ No newline at end of file + From 27ed684bd944b9851aa2589ee0191a55a7d2fb57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Thu, 17 Apr 2025 21:00:08 +0200 Subject: [PATCH 17/33] Update feat-createeventwithcategoriesandtickettyped_resellio.yml --- .../feat-createeventwithcategoriesandtickettyped_resellio.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml b/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml index f54eca3..d46be99 100644 --- a/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml +++ b/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml @@ -27,13 +27,13 @@ jobs: run: dotnet build --configuration Release - name: dotnet publish - run: dotnet publish -c Release -o "${{env.DOTNET_ROOT}}/TickApi" + run: dotnet publish -c Release -o "${{env.DOTNET_ROOT}}/TickAPI/TickAPI.sln" - name: Upload artifact for deployment job uses: actions/upload-artifact@v4 with: name: .net-app - path: ${{env.DOTNET_ROOT}}/TickApi + path: ${{env.DOTNET_ROOT}}/TickAPI/TickAPI.sln deploy: runs-on: windows-latest From ea3546a3e172a577faac43530df310cf69b885a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Thu, 17 Apr 2025 21:04:46 +0200 Subject: [PATCH 18/33] Update feat-createeventwithcategoriesandtickettyped_resellio.yml --- ...twithcategoriesandtickettyped_resellio.yml | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml b/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml index d46be99..bec4fa9 100644 --- a/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml +++ b/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml @@ -1,40 +1,36 @@ # Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy # More GitHub Actions for Azure: https://github.com/Azure/actions - name: Build and deploy ASP.Net Core app to Azure Web App - resellio - on: push: branches: - feat/CreateEventWithCategoriesAndTicketTyped workflow_dispatch: - jobs: build: runs-on: windows-latest permissions: contents: read #This is required for actions/checkout - steps: - uses: actions/checkout@v4 - + - name: Set up .NET Core uses: actions/setup-dotnet@v4 with: dotnet-version: '6.0.x' - + - name: Build with dotnet - run: dotnet build --configuration Release - + run: dotnet build TickAPI/TickAPI.sln --configuration Release + - name: dotnet publish - run: dotnet publish -c Release -o "${{env.DOTNET_ROOT}}/TickAPI/TickAPI.sln" - + run: dotnet publish TickAPI/TickAPI.sln -c Release -o "${{env.DOTNET_ROOT}}/myapp" + - name: Upload artifact for deployment job uses: actions/upload-artifact@v4 with: name: .net-app - path: ${{env.DOTNET_ROOT}}/TickAPI/TickAPI.sln - + path: ${{env.DOTNET_ROOT}}/myapp + deploy: runs-on: windows-latest needs: build @@ -44,7 +40,6 @@ jobs: permissions: id-token: write #This is required for requesting the JWT contents: read #This is required for actions/checkout - steps: - name: Download artifact from build job uses: actions/download-artifact@v4 @@ -54,10 +49,10 @@ jobs: - name: Login to Azure uses: azure/login@v2 with: - client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_1E79017744574753935FA54217321744 }} - tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_45CB50561E614FBB9482DD79882CEA2A }} - subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_036603283F034371B4B2C33640B40CEB }} - + client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_0D0336DEAF734574B53DD4A5D2E898A0 }} + tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_800D316A4C714278AB484F215A6303F0 }} + subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_E2CF62C6C3CB48B0AFF01965324F5D3A }} + - name: Deploy to Azure Web App id: deploy-to-webapp uses: azure/webapps-deploy@v3 @@ -65,4 +60,3 @@ jobs: app-name: 'resellio' slot-name: 'Production' package: . - From bc1ba00ac946c6d15d46110376c6b79114bf7c27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Thu, 17 Apr 2025 21:17:43 +0200 Subject: [PATCH 19/33] Update feat-createeventwithcategoriesandtickettyped_resellio.yml --- .../feat-createeventwithcategoriesandtickettyped_resellio.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml b/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml index bec4fa9..fc03c07 100644 --- a/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml +++ b/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml @@ -20,10 +20,10 @@ jobs: dotnet-version: '6.0.x' - name: Build with dotnet - run: dotnet build TickAPI/TickAPI.sln --configuration Release + run: dotnet build TickAPI/TickAPI/TickAPI.csproj --configuration Release - name: dotnet publish - run: dotnet publish TickAPI/TickAPI.sln -c Release -o "${{env.DOTNET_ROOT}}/myapp" + run: dotnet publish TickAPI/TickAPI/TickAPI.csproj -c Release -o "${{env.DOTNET_ROOT}}/myapp" - name: Upload artifact for deployment job uses: actions/upload-artifact@v4 From 125d691b181c9c5eec2d89026de8d16826fe24f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Thu, 17 Apr 2025 21:24:52 +0200 Subject: [PATCH 20/33] Delete .github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml --- ...twithcategoriesandtickettyped_resellio.yml | 62 ------------------- 1 file changed, 62 deletions(-) delete mode 100644 .github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml diff --git a/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml b/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml deleted file mode 100644 index fc03c07..0000000 --- a/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml +++ /dev/null @@ -1,62 +0,0 @@ -# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy -# More GitHub Actions for Azure: https://github.com/Azure/actions -name: Build and deploy ASP.Net Core app to Azure Web App - resellio -on: - push: - branches: - - feat/CreateEventWithCategoriesAndTicketTyped - workflow_dispatch: -jobs: - build: - runs-on: windows-latest - permissions: - contents: read #This is required for actions/checkout - steps: - - uses: actions/checkout@v4 - - - name: Set up .NET Core - uses: actions/setup-dotnet@v4 - with: - dotnet-version: '6.0.x' - - - name: Build with dotnet - run: dotnet build TickAPI/TickAPI/TickAPI.csproj --configuration Release - - - name: dotnet publish - run: dotnet publish TickAPI/TickAPI/TickAPI.csproj -c Release -o "${{env.DOTNET_ROOT}}/myapp" - - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v4 - with: - name: .net-app - path: ${{env.DOTNET_ROOT}}/myapp - - deploy: - runs-on: windows-latest - needs: build - environment: - name: 'Production' - url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} - permissions: - id-token: write #This is required for requesting the JWT - contents: read #This is required for actions/checkout - steps: - - name: Download artifact from build job - uses: actions/download-artifact@v4 - with: - name: .net-app - - - name: Login to Azure - uses: azure/login@v2 - with: - client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_0D0336DEAF734574B53DD4A5D2E898A0 }} - tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_800D316A4C714278AB484F215A6303F0 }} - subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_E2CF62C6C3CB48B0AFF01965324F5D3A }} - - - name: Deploy to Azure Web App - id: deploy-to-webapp - uses: azure/webapps-deploy@v3 - with: - app-name: 'resellio' - slot-name: 'Production' - package: . From 8fa7d7e9f62eca0df8060d05029275e8d36f5d09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Thu, 17 Apr 2025 21:34:57 +0200 Subject: [PATCH 21/33] Add or update the Azure App Service build and deployment workflow config --- ...twithcategoriesandtickettyped_resellio.yml | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 .github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml diff --git a/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml b/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml new file mode 100644 index 0000000..5dc9ed9 --- /dev/null +++ b/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml @@ -0,0 +1,68 @@ +# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy +# More GitHub Actions for Azure: https://github.com/Azure/actions + +name: Build and deploy ASP.Net Core app to Azure Web App - resellio + +on: + push: + branches: + - feat/CreateEventWithCategoriesAndTicketTyped + workflow_dispatch: + +jobs: + build: + runs-on: windows-latest + permissions: + contents: read #This is required for actions/checkout + + steps: + - uses: actions/checkout@v4 + + - name: Set up .NET Core + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '9.x' + + - name: Build with dotnet + run: dotnet build --configuration Release + + - name: dotnet publish + run: dotnet publish -c Release -o "${{env.DOTNET_ROOT}}/myapp" + + - name: Upload artifact for deployment job + uses: actions/upload-artifact@v4 + with: + name: .net-app + path: ${{env.DOTNET_ROOT}}/myapp + + deploy: + runs-on: windows-latest + needs: build + environment: + name: 'Production' + url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} + permissions: + id-token: write #This is required for requesting the JWT + contents: read #This is required for actions/checkout + + steps: + - name: Download artifact from build job + uses: actions/download-artifact@v4 + with: + name: .net-app + + - name: Login to Azure + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_F22C931708554F8B83EE4F83C4FED407 }} + tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_6CDAC678ACD94858BF3421F606456B8B }} + subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_CA368EC8EA37446E96D5DF5F42B650EA }} + + - name: Deploy to Azure Web App + id: deploy-to-webapp + uses: azure/webapps-deploy@v3 + with: + app-name: 'resellio' + slot-name: 'Production' + package: . + \ No newline at end of file From 18b9dc022ca202109c026ba842b3817fabf54a0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Thu, 17 Apr 2025 21:36:35 +0200 Subject: [PATCH 22/33] Update feat-createeventwithcategoriesandtickettyped_resellio.yml --- ...twithcategoriesandtickettyped_resellio.yml | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml b/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml index 5dc9ed9..5971dad 100644 --- a/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml +++ b/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml @@ -24,10 +24,10 @@ jobs: dotnet-version: '9.x' - name: Build with dotnet - run: dotnet build --configuration Release + run: dotnet build TIckAPI/TickAPI.sln --configuration Release - name: dotnet publish - run: dotnet publish -c Release -o "${{env.DOTNET_ROOT}}/myapp" + run: dotnet publish TIckAPI/TickAPI.sln -c Release -o "${{env.DOTNET_ROOT}}/myapp" - name: Upload artifact for deployment job uses: actions/upload-artifact@v4 @@ -38,25 +38,25 @@ jobs: deploy: runs-on: windows-latest needs: build - environment: - name: 'Production' + environment: + name: 'Production' url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} - permissions: - id-token: write #This is required for requesting the JWT - contents: read #This is required for actions/checkout + permissions: + id-token: write #This is required for requesting the JWT + contents: read #This is required for actions/checkout steps: - name: Download artifact from build job uses: actions/download-artifact@v4 with: name: .net-app - - - name: Login to Azure - uses: azure/login@v2 - with: - client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_F22C931708554F8B83EE4F83C4FED407 }} - tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_6CDAC678ACD94858BF3421F606456B8B }} - subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_CA368EC8EA37446E96D5DF5F42B650EA }} + + - name: Login to Azure + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_F22C931708554F8B83EE4F83C4FED407 }} + tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_6CDAC678ACD94858BF3421F606456B8B }} + subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_CA368EC8EA37446E96D5DF5F42B650EA }} - name: Deploy to Azure Web App id: deploy-to-webapp @@ -65,4 +65,4 @@ jobs: app-name: 'resellio' slot-name: 'Production' package: . - \ No newline at end of file + From 23087d1cb8501b72a393b3e52ea43aaf1ac6a618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Thu, 17 Apr 2025 21:44:41 +0200 Subject: [PATCH 23/33] Delete .github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml --- ...twithcategoriesandtickettyped_resellio.yml | 68 ------------------- 1 file changed, 68 deletions(-) delete mode 100644 .github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml diff --git a/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml b/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml deleted file mode 100644 index 5971dad..0000000 --- a/.github/workflows/feat-createeventwithcategoriesandtickettyped_resellio.yml +++ /dev/null @@ -1,68 +0,0 @@ -# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy -# More GitHub Actions for Azure: https://github.com/Azure/actions - -name: Build and deploy ASP.Net Core app to Azure Web App - resellio - -on: - push: - branches: - - feat/CreateEventWithCategoriesAndTicketTyped - workflow_dispatch: - -jobs: - build: - runs-on: windows-latest - permissions: - contents: read #This is required for actions/checkout - - steps: - - uses: actions/checkout@v4 - - - name: Set up .NET Core - uses: actions/setup-dotnet@v4 - with: - dotnet-version: '9.x' - - - name: Build with dotnet - run: dotnet build TIckAPI/TickAPI.sln --configuration Release - - - name: dotnet publish - run: dotnet publish TIckAPI/TickAPI.sln -c Release -o "${{env.DOTNET_ROOT}}/myapp" - - - name: Upload artifact for deployment job - uses: actions/upload-artifact@v4 - with: - name: .net-app - path: ${{env.DOTNET_ROOT}}/myapp - - deploy: - runs-on: windows-latest - needs: build - environment: - name: 'Production' - url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} - permissions: - id-token: write #This is required for requesting the JWT - contents: read #This is required for actions/checkout - - steps: - - name: Download artifact from build job - uses: actions/download-artifact@v4 - with: - name: .net-app - - - name: Login to Azure - uses: azure/login@v2 - with: - client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_F22C931708554F8B83EE4F83C4FED407 }} - tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_6CDAC678ACD94858BF3421F606456B8B }} - subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_CA368EC8EA37446E96D5DF5F42B650EA }} - - - name: Deploy to Azure Web App - id: deploy-to-webapp - uses: azure/webapps-deploy@v3 - with: - app-name: 'resellio' - slot-name: 'Production' - package: . - From 02723bbf92648568c7ba73a10bbecc9d5595b48c Mon Sep 17 00:00:00 2001 From: kubapoke Date: Sat, 19 Apr 2025 01:08:27 +0200 Subject: [PATCH 24/33] updated controller/endpoint names --- ...rTests.cs => CategoriesControllerTests.cs} | 6 ++--- ...erTests.cs => CustomersControllerTests.cs} | 10 +++---- ...ollerTests.cs => EventsControllerTests.cs} | 26 +++++++++---------- ...rTests.cs => OrganizersControllerTests.cs} | 20 +++++++------- ...AdminController.cs => AdminsController.cs} | 2 +- ...yController.cs => CategoriesController.cs} | 8 +++--- ...erController.cs => CustomersController.cs} | 4 +-- ...EventController.cs => EventsController.cs} | 14 +++++----- ...rController.cs => OrganizersController.cs} | 8 +++--- ...cketController.cs => TicketsController.cs} | 2 +- 10 files changed, 50 insertions(+), 50 deletions(-) rename TickAPI/TickAPI.Tests/Categories/Controllers/{CategoryControllerTests.cs => CategoriesControllerTests.cs} (92%) rename TickAPI/TickAPI.Tests/Customers/Controllers/{CustomerControllerTests.cs => CustomersControllerTests.cs} (97%) rename TickAPI/TickAPI.Tests/Events/Controllers/{EventControllerTests.cs => EventsControllerTests.cs} (93%) rename TickAPI/TickAPI.Tests/Organizers/Controllers/{OrganizerControllerTests.cs => OrganizersControllerTests.cs} (97%) rename TickAPI/TickAPI/Admins/Controllers/{AdminController.cs => AdminsController.cs} (72%) rename TickAPI/TickAPI/Categories/Controllers/{CategoryController.cs => CategoriesController.cs} (89%) rename TickAPI/TickAPI/Customers/Controllers/{CustomerController.cs => CustomersController.cs} (93%) rename TickAPI/TickAPI/Events/Controllers/{EventController.cs => EventsController.cs} (93%) rename TickAPI/TickAPI/Organizers/Controllers/{OrganizerController.cs => OrganizersController.cs} (96%) rename TickAPI/TickAPI/Tickets/Controllers/{TicketController.cs => TicketsController.cs} (72%) diff --git a/TickAPI/TickAPI.Tests/Categories/Controllers/CategoryControllerTests.cs b/TickAPI/TickAPI.Tests/Categories/Controllers/CategoriesControllerTests.cs similarity index 92% rename from TickAPI/TickAPI.Tests/Categories/Controllers/CategoryControllerTests.cs rename to TickAPI/TickAPI.Tests/Categories/Controllers/CategoriesControllerTests.cs index 7a0c8f0..271fd24 100644 --- a/TickAPI/TickAPI.Tests/Categories/Controllers/CategoryControllerTests.cs +++ b/TickAPI/TickAPI.Tests/Categories/Controllers/CategoriesControllerTests.cs @@ -12,7 +12,7 @@ namespace TickAPI.Tests.Categories.Controllers; -public class CategoryControllerTests +public class CategoriesControllerTests { [Fact] public async Task GetCategories_WhenDataIsValid_ShouldReturnOk() @@ -25,7 +25,7 @@ public async Task GetCategories_WhenDataIsValid_ShouldReturnOk() Result>.Success(new PaginatedData(new List(), pageNumber, pageSize, true, true, new PaginationDetails(0, 0)))); - var sut = new CategoryController(categoryServiceMock.Object); + var sut = new CategoriesController(categoryServiceMock.Object); // Act var res = await sut.GetCategories(pageSize, pageNumber); @@ -49,7 +49,7 @@ public async Task CreateCategory_WhenDataIsValid_ShouldReturnSuccess() .Setup(m => m.CreateNewCategoryAsync(categoryName)) .ReturnsAsync(Result.Success(new Category())); - var sut = new CategoryController(categoryServiceMock.Object); + var sut = new CategoriesController(categoryServiceMock.Object); // Act var res = await sut.CreateCategory(createCategoryDto); diff --git a/TickAPI/TickAPI.Tests/Customers/Controllers/CustomerControllerTests.cs b/TickAPI/TickAPI.Tests/Customers/Controllers/CustomersControllerTests.cs similarity index 97% rename from TickAPI/TickAPI.Tests/Customers/Controllers/CustomerControllerTests.cs rename to TickAPI/TickAPI.Tests/Customers/Controllers/CustomersControllerTests.cs index 8e9eadd..e7ce3a2 100644 --- a/TickAPI/TickAPI.Tests/Customers/Controllers/CustomerControllerTests.cs +++ b/TickAPI/TickAPI.Tests/Customers/Controllers/CustomersControllerTests.cs @@ -14,7 +14,7 @@ namespace TickAPI.Tests.Customers.Controllers; -public class CustomerControllerTests +public class CustomersControllerTests { [Fact] public async Task GoogleLogin_WhenAuthSuccessAndCustomerExists_ShouldReturnToken() @@ -38,7 +38,7 @@ public async Task GoogleLogin_WhenAuthSuccessAndCustomerExists_ShouldReturnToken var claimsServiceMock = new Mock(); - var sut = new CustomerController( + var sut = new CustomersController( googleAuthServiceMock.Object, jwtServiceMock.Object, customerServiceMock.Object, @@ -83,7 +83,7 @@ public async Task GoogleLogin_WhenAuthSuccessAndCustomerDoesNotExist_ShouldCreat var claimsServiceMock = new Mock(); - var sut = new CustomerController( + var sut = new CustomersController( googleAuthServiceMock.Object, jwtServiceMock.Object, customerServiceMock.Object, @@ -137,7 +137,7 @@ public async Task AboutMe_WithValidEmailClaim_ShouldReturnCustomerDetails() var claimsServiceMock = new Mock(); claimsServiceMock.Setup(m => m.GetEmailFromClaims(controllerContext.HttpContext.User.Claims)).Returns(Result.Success(email)); - var sut = new CustomerController( + var sut = new CustomersController( googleAuthServiceMock.Object, jwtServiceMock.Object, customerServiceMock.Object, @@ -168,7 +168,7 @@ public async Task AboutMe_WithMissingEmailClaim_ShouldReturnBadRequest() claimsServiceMock.Setup(m => m.GetEmailFromClaims(It.IsAny>())).Returns(Result.Failure(StatusCodes.Status400BadRequest, "missing email claim")); - var sut = new CustomerController( + var sut = new CustomersController( googleAuthServiceMock.Object, jwtServiceMock.Object, customerServiceMock.Object, diff --git a/TickAPI/TickAPI.Tests/Events/Controllers/EventControllerTests.cs b/TickAPI/TickAPI.Tests/Events/Controllers/EventsControllerTests.cs similarity index 93% rename from TickAPI/TickAPI.Tests/Events/Controllers/EventControllerTests.cs rename to TickAPI/TickAPI.Tests/Events/Controllers/EventsControllerTests.cs index 8c788b1..23c3511 100644 --- a/TickAPI/TickAPI.Tests/Events/Controllers/EventControllerTests.cs +++ b/TickAPI/TickAPI.Tests/Events/Controllers/EventsControllerTests.cs @@ -16,7 +16,7 @@ namespace TickAPI.Tests.Events.Controllers; -public class EventControllerTests +public class EventsControllerTests { [Fact] public async Task CreateEvent_WhenDataIsValid_ShouldReturnSuccess() @@ -55,7 +55,7 @@ public async Task CreateEvent_WhenDataIsValid_ShouldReturnSuccess() var organizerServiceMock = new Mock(); - var sut = new EventController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); + var sut = new EventsController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); sut.ControllerContext = controllerContext; @@ -87,7 +87,7 @@ public async Task CreateEvent_WhenMissingEmailClaims_ShouldReturnBadRequest() var organizerServiceMock = new Mock(); - var sut = new EventController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); + var sut = new EventsController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); sut.ControllerContext = new ControllerContext { @@ -158,7 +158,7 @@ public async Task GetOrganizerEvents_WhenAllOperationsSucceed_ShouldReturnOkWith .Setup(m => m.GetOrganizerEventsAsync(organizer, page, pageSize)) .ReturnsAsync(Result>.Success(paginatedData)); - var sut = new EventController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); + var sut = new EventsController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); sut.ControllerContext = controllerContext; // Act @@ -195,7 +195,7 @@ public async Task GetOrganizerEvents_WhenEmailClaimIsMissing_ShouldReturnBadRequ var eventServiceMock = new Mock(); var organizerServiceMock = new Mock(); - var sut = new EventController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); + var sut = new EventsController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); sut.ControllerContext = new ControllerContext { HttpContext = new DefaultHttpContext @@ -248,7 +248,7 @@ public async Task GetOrganizerEvents_WhenOrganizerIsNotFound_ShouldReturnNotFoun var eventServiceMock = new Mock(); - var sut = new EventController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); + var sut = new EventsController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); sut.ControllerContext = controllerContext; // Act @@ -300,7 +300,7 @@ public async Task GetOrganizerEvents_WhenPaginationFails_ShouldReturnBadRequest( .Setup(m => m.GetOrganizerEventsAsync(organizer, page, pageSize)) .ReturnsAsync(Result>.Failure(StatusCodes.Status400BadRequest, errorMessage)); - var sut = new EventController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); + var sut = new EventsController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); sut.ControllerContext = controllerContext; // Act @@ -352,7 +352,7 @@ public async Task GetOrganizerEventsPaginationDetails_WhenAllOperationsSucceed_S .Setup(m => m.GetOrganizerEventsPaginationDetailsAsync(organizer, pageSize)) .ReturnsAsync(Result.Success(paginationDetails)); - var sut = new EventController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); + var sut = new EventsController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); sut.ControllerContext = controllerContext; // Act @@ -406,7 +406,7 @@ public async Task GetOrganizerEventsPaginationDetails_WhenPaginationDetailsFails .Setup(m => m.GetOrganizerEventsPaginationDetailsAsync(organizer, pageSize)) .ReturnsAsync(Result.Failure(StatusCodes.Status400BadRequest, errorMessage)); - var sut = new EventController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); + var sut = new EventsController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); sut.ControllerContext = controllerContext; // Act @@ -447,7 +447,7 @@ public async Task GetEvents_WhenAllOperationsSucceed_ShouldReturnOkWithPaginated .Setup(m => m.GetEventsAsync(page, pageSize)) .ReturnsAsync(Result>.Success(paginatedData)); - var sut = new EventController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); + var sut = new EventsController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); // Act var response = await sut.GetEvents(pageSize, page); @@ -484,7 +484,7 @@ public async Task GetEvents_WhenOperationFails_ShouldReturnErrorWithCorrectStatu .Setup(m => m.GetEventsAsync(page, pageSize)) .ReturnsAsync(Result>.Failure(statusCode, errorMessage)); - var sut = new EventController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); + var sut = new EventsController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); // Act var response = await sut.GetEvents(pageSize, page); @@ -512,7 +512,7 @@ public async Task GetEventsPaginationDetails_WhenAllOperationsSucceed_ShouldRetu .Setup(m => m.GetEventsPaginationDetailsAsync(pageSize)) .ReturnsAsync(Result.Success(paginationDetails)); - var sut = new EventController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); + var sut = new EventsController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); // Act var response = await sut.GetEventsPaginationDetails(pageSize); @@ -543,7 +543,7 @@ public async Task GetEventsPaginationDetails_WhenOperationFails_ShouldReturnErro .Setup(m => m.GetEventsPaginationDetailsAsync(pageSize)) .ReturnsAsync(Result.Failure(statusCode, errorMessage)); - var sut = new EventController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); + var sut = new EventsController(eventServiceMock.Object, claimsServiceMock.Object, organizerServiceMock.Object); // Act var response = await sut.GetEventsPaginationDetails(pageSize); diff --git a/TickAPI/TickAPI.Tests/Organizers/Controllers/OrganizerControllerTests.cs b/TickAPI/TickAPI.Tests/Organizers/Controllers/OrganizersControllerTests.cs similarity index 97% rename from TickAPI/TickAPI.Tests/Organizers/Controllers/OrganizerControllerTests.cs rename to TickAPI/TickAPI.Tests/Organizers/Controllers/OrganizersControllerTests.cs index 5e26e85..164b26c 100644 --- a/TickAPI/TickAPI.Tests/Organizers/Controllers/OrganizerControllerTests.cs +++ b/TickAPI/TickAPI.Tests/Organizers/Controllers/OrganizersControllerTests.cs @@ -17,7 +17,7 @@ namespace TickAPI.Tests.Organizers.Controllers; -public class OrganizerControllerTests +public class OrganizersControllerTests { [Fact] public async Task GoogleLogin_WhenAuthSuccessAndVerifiedOrganizerExists_ShouldReturnValidVerifiedLoginDto() @@ -44,7 +44,7 @@ public async Task GoogleLogin_WhenAuthSuccessAndVerifiedOrganizerExists_ShouldRe var claimsServiceMock = new Mock(); - var sut = new OrganizerController( + var sut = new OrganizersController( googleAuthServiceMock.Object, jwtServiceMock.Object, organizerServiceMock.Object, @@ -85,7 +85,7 @@ public async Task GoogleLogin_WhenAuthSuccessAndUnverifiedOrganizerExists_Should var claimsServiceMock = new Mock(); - var sut = new OrganizerController( + var sut = new OrganizersController( googleAuthServiceMock.Object, jwtServiceMock.Object, organizerServiceMock.Object, @@ -127,7 +127,7 @@ public async Task var claimsServiceMock = new Mock(); - var sut = new OrganizerController( + var sut = new OrganizersController( googleAuthServiceMock.Object, jwtServiceMock.Object, organizerServiceMock.Object, @@ -189,7 +189,7 @@ public async Task CreateOrganizer_WhenCreatingAccountIsSuccessful_ShouldReturnTo var claimsServiceMock = new Mock(); claimsServiceMock.Setup(m => m.GetEmailFromClaims(controllerContext.HttpContext.User.Claims)).Returns(Result.Success(email)); - var sut = new OrganizerController( + var sut = new OrganizersController( googleAuthServiceMock.Object, jwtServiceMock.Object, organizerServiceMock.Object, @@ -218,7 +218,7 @@ public async Task CreateOrganizer_WhenMissingEmailClaim_ShouldReturnBadRequest() var claimsServiceMock = new Mock(); claimsServiceMock.Setup(m => m.GetEmailFromClaims(It.IsAny>())).Returns(Result.Failure(StatusCodes.Status400BadRequest, "missing email claim")); - var sut = new OrganizerController( + var sut = new OrganizersController( googleAuthServiceMock.Object, jwtServiceMock.Object, organizerServiceMock.Object, @@ -258,7 +258,7 @@ public async Task VerifyOrganizer_WhenVerificationSuccessful_ShouldReturnOk() var claimsServiceMock = new Mock(); - var sut = new OrganizerController( + var sut = new OrganizersController( googleAuthServiceMock.Object, jwtServiceMock.Object, organizerServiceMock.Object, @@ -318,7 +318,7 @@ public async Task AboutMe_WithValidEmailClaim_ShouldReturnOrganizerDetails() var claimsServiceMock = new Mock(); claimsServiceMock.Setup(m => m.GetEmailFromClaims(controllerContext.HttpContext.User.Claims)).Returns(Result.Success(email)); - var sut = new OrganizerController( + var sut = new OrganizersController( googleAuthServiceMock.Object, jwtServiceMock.Object, organizerServiceMock.Object, @@ -351,7 +351,7 @@ public async Task AboutMe_WithMissingEmailClaim_ShouldReturnBadRequest() var claimsServiceMock = new Mock(); claimsServiceMock.Setup(m => m.GetEmailFromClaims(It.IsAny>())).Returns(Result.Failure(StatusCodes.Status400BadRequest, "missing email claim")); - var sut = new OrganizerController( + var sut = new OrganizersController( googleAuthServiceMock.Object, jwtServiceMock.Object, organizerServiceMock.Object, @@ -404,7 +404,7 @@ public async Task AboutMe_WhenOrganizerNotFound_ShouldReturnInternalServerError( var claimsServiceMock = new Mock(); claimsServiceMock.Setup(m => m.GetEmailFromClaims(controllerContext.HttpContext.User.Claims)).Returns(Result.Success(email)); - var sut = new OrganizerController( + var sut = new OrganizersController( googleAuthServiceMock.Object, jwtServiceMock.Object, organizerServiceMock.Object, diff --git a/TickAPI/TickAPI/Admins/Controllers/AdminController.cs b/TickAPI/TickAPI/Admins/Controllers/AdminsController.cs similarity index 72% rename from TickAPI/TickAPI/Admins/Controllers/AdminController.cs rename to TickAPI/TickAPI/Admins/Controllers/AdminsController.cs index 63e23b2..cbc77bb 100644 --- a/TickAPI/TickAPI/Admins/Controllers/AdminController.cs +++ b/TickAPI/TickAPI/Admins/Controllers/AdminsController.cs @@ -4,7 +4,7 @@ namespace TickAPI.Admins.Controllers; [ApiController] [Route("api/[controller]")] -public class AdminController : ControllerBase +public class AdminsController : ControllerBase { } \ No newline at end of file diff --git a/TickAPI/TickAPI/Categories/Controllers/CategoryController.cs b/TickAPI/TickAPI/Categories/Controllers/CategoriesController.cs similarity index 89% rename from TickAPI/TickAPI/Categories/Controllers/CategoryController.cs rename to TickAPI/TickAPI/Categories/Controllers/CategoriesController.cs index 7ec4ea6..684f0bc 100644 --- a/TickAPI/TickAPI/Categories/Controllers/CategoryController.cs +++ b/TickAPI/TickAPI/Categories/Controllers/CategoriesController.cs @@ -10,17 +10,17 @@ namespace TickAPI.Categories.Controllers; [ApiController] [Route("api/[controller]")] -public class CategoryController : Controller +public class CategoriesController : Controller { private readonly ICategoryService _categoryService; - public CategoryController(ICategoryService categoryService) + public CategoriesController(ICategoryService categoryService) { _categoryService = categoryService; } [AuthorizeWithPolicy(AuthPolicies.VerifiedUserPolicy)] - [HttpGet("categories")] + [HttpGet] public async Task>> GetCategories([FromQuery] int pageSize, [FromQuery] int page) { var res = await _categoryService.GetCategoriesResponsesAsync(pageSize, page); @@ -32,7 +32,7 @@ public async Task>> GetCatego } // TODO: Add appropriate policy verification (admin, maybe also organizer?) - [HttpPost("category")] + [HttpPost] public async Task CreateCategory([FromBody] CreateCategoryDto request) { var newCategoryResult = await _categoryService.CreateNewCategoryAsync(request.Name); diff --git a/TickAPI/TickAPI/Customers/Controllers/CustomerController.cs b/TickAPI/TickAPI/Customers/Controllers/CustomersController.cs similarity index 93% rename from TickAPI/TickAPI/Customers/Controllers/CustomerController.cs rename to TickAPI/TickAPI/Customers/Controllers/CustomersController.cs index 6b5caaf..4ec0730 100644 --- a/TickAPI/TickAPI/Customers/Controllers/CustomerController.cs +++ b/TickAPI/TickAPI/Customers/Controllers/CustomersController.cs @@ -11,14 +11,14 @@ namespace TickAPI.Customers.Controllers; [ApiController] [Route("api/[controller]")] -public class CustomerController : ControllerBase +public class CustomersController : ControllerBase { private readonly IGoogleAuthService _googleAuthService; private readonly IJwtService _jwtService; private readonly ICustomerService _customerService; private readonly IClaimsService _claimsService; - public CustomerController(IGoogleAuthService googleAuthService, IJwtService jwtService, ICustomerService customerService, IClaimsService claimsService) + public CustomersController(IGoogleAuthService googleAuthService, IJwtService jwtService, ICustomerService customerService, IClaimsService claimsService) { _googleAuthService = googleAuthService; _jwtService = jwtService; diff --git a/TickAPI/TickAPI/Events/Controllers/EventController.cs b/TickAPI/TickAPI/Events/Controllers/EventsController.cs similarity index 93% rename from TickAPI/TickAPI/Events/Controllers/EventController.cs rename to TickAPI/TickAPI/Events/Controllers/EventsController.cs index 09b2e65..1c50747 100644 --- a/TickAPI/TickAPI/Events/Controllers/EventController.cs +++ b/TickAPI/TickAPI/Events/Controllers/EventsController.cs @@ -14,13 +14,13 @@ namespace TickAPI.Events.Controllers; [Route("api/[controller]")] // TODO: Add lists of categories and tickettypes -public class EventController : ControllerBase +public class EventsController : ControllerBase { private readonly IEventService _eventService; private readonly IClaimsService _claimsService; private readonly IOrganizerService _organizerService; - public EventController(IEventService eventService, IClaimsService claimsService, IOrganizerService organizerService) + public EventsController(IEventService eventService, IClaimsService claimsService, IOrganizerService organizerService) { _eventService = eventService; _claimsService = claimsService; @@ -28,7 +28,7 @@ public EventController(IEventService eventService, IClaimsService claimsService, } [AuthorizeWithPolicy(AuthPolicies.VerifiedOrganizerPolicy)] - [HttpPost("event")] + [HttpPost] public async Task> CreateEvent([FromBody] CreateEventDto request) { var emailResult = _claimsService.GetEmailFromClaims(User.Claims); @@ -47,7 +47,7 @@ public async Task> CreateEvent([FromBody] C } [AuthorizeWithPolicy(AuthPolicies.VerifiedOrganizerPolicy)] - [HttpGet("organizer-events")] + [HttpGet("organizer")] public async Task>> GetOrganizerEvents([FromQuery] int pageSize, [FromQuery] int page) { var emailResult = _claimsService.GetEmailFromClaims(User.Claims); @@ -74,7 +74,7 @@ public async Task>> GetOrganizer } [AuthorizeWithPolicy(AuthPolicies.VerifiedOrganizerPolicy)] - [HttpGet("organizer-events-pagination-details")] + [HttpGet("organizer-pagination-details")] public async Task> GetOrganizerEventsPaginationDetails([FromQuery] int pageSize) { var emailResult = _claimsService.GetEmailFromClaims(User.Claims); @@ -101,7 +101,7 @@ public async Task> GetOrganizerEventsPaginationD } [AuthorizeWithPolicy(AuthPolicies.CustomerPolicy)] - [HttpGet("events")] + [HttpGet] public async Task>> GetEvents([FromQuery] int pageSize, [FromQuery] int page) { var paginatedDataResult = await _eventService.GetEventsAsync(page, pageSize); @@ -113,7 +113,7 @@ public async Task>> GetEvents([F } [AuthorizeWithPolicy(AuthPolicies.CustomerPolicy)] - [HttpGet("events-pagination-details")] + [HttpGet("pagination-details")] public async Task> GetEventsPaginationDetails([FromQuery] int pageSize) { var paginationDetailsResult = await _eventService.GetEventsPaginationDetailsAsync(pageSize); diff --git a/TickAPI/TickAPI/Organizers/Controllers/OrganizerController.cs b/TickAPI/TickAPI/Organizers/Controllers/OrganizersController.cs similarity index 96% rename from TickAPI/TickAPI/Organizers/Controllers/OrganizerController.cs rename to TickAPI/TickAPI/Organizers/Controllers/OrganizersController.cs index a4644d6..cb405e3 100644 --- a/TickAPI/TickAPI/Organizers/Controllers/OrganizerController.cs +++ b/TickAPI/TickAPI/Organizers/Controllers/OrganizersController.cs @@ -12,14 +12,14 @@ namespace TickAPI.Organizers.Controllers; [ApiController] [Route("api/[controller]")] -public class OrganizerController : ControllerBase +public class OrganizersController : ControllerBase { private readonly IGoogleAuthService _googleAuthService; private readonly IJwtService _jwtService; private readonly IOrganizerService _organizerService; private readonly IClaimsService _claimsService; - public OrganizerController(IGoogleAuthService googleAuthService, IJwtService jwtService, + public OrganizersController(IGoogleAuthService googleAuthService, IJwtService jwtService, IOrganizerService organizerService, IClaimsService claimsService) { _googleAuthService = googleAuthService; @@ -62,7 +62,7 @@ public async Task> GoogleLogin([Fr } [AuthorizeWithPolicy(AuthPolicies.NewOrganizerPolicy)] - [HttpPost("organizer")] + [HttpPost] public async Task> CreateOrganizer([FromBody] CreateOrganizerDto request) { var emailResult = _claimsService.GetEmailFromClaims(User.Claims); @@ -84,7 +84,7 @@ public async Task> CreateOrganizer([Fro } // TODO: Add authorization with admin policy here - [HttpPost("verify-organizer")] + [HttpPost("verify")] public async Task VerifyOrganizer([FromBody] VerifyOrganizerDto request) { var verifyOrganizerResult = await _organizerService.VerifyOrganizerByEmailAsync(request.Email); diff --git a/TickAPI/TickAPI/Tickets/Controllers/TicketController.cs b/TickAPI/TickAPI/Tickets/Controllers/TicketsController.cs similarity index 72% rename from TickAPI/TickAPI/Tickets/Controllers/TicketController.cs rename to TickAPI/TickAPI/Tickets/Controllers/TicketsController.cs index fa02f1f..fcf4467 100644 --- a/TickAPI/TickAPI/Tickets/Controllers/TicketController.cs +++ b/TickAPI/TickAPI/Tickets/Controllers/TicketsController.cs @@ -4,7 +4,7 @@ namespace TickAPI.Tickets.Controllers; [ApiController] [Route("api/[controller]")] -public class TicketController : ControllerBase +public class TicketsController : ControllerBase { } \ No newline at end of file From d7ba66ea6cb7e95c81283732e521f6cfc96532b4 Mon Sep 17 00:00:00 2001 From: kubapoke Date: Sat, 19 Apr 2025 01:36:40 +0200 Subject: [PATCH 25/33] Changed EventFilter into a non-service class --- .../Events/{Services => Filters}/EventFilterTests.cs | 4 ++-- TickAPI/TickAPI/Events/{Services => Filters}/EventFilter.cs | 2 +- TickAPI/TickAPI/Program.cs | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) rename TickAPI/TickAPI.Tests/Events/{Services => Filters}/EventFilterTests.cs (99%) rename TickAPI/TickAPI/Events/{Services => Filters}/EventFilter.cs (98%) diff --git a/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs b/TickAPI/TickAPI.Tests/Events/Filters/EventFilterTests.cs similarity index 99% rename from TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs rename to TickAPI/TickAPI.Tests/Events/Filters/EventFilterTests.cs index a630b39..6458b6e 100644 --- a/TickAPI/TickAPI.Tests/Events/Services/EventFilterTests.cs +++ b/TickAPI/TickAPI.Tests/Events/Filters/EventFilterTests.cs @@ -1,10 +1,10 @@ using TickAPI.Addresses.Models; using TickAPI.Categories.Models; +using TickAPI.Events.Filters; using TickAPI.Events.Models; -using TickAPI.Events.Services; using TickAPI.TicketTypes.Models; -namespace TickAPI.Tests.Events.Services; +namespace TickAPI.Tests.Events.Filters; public class EventFilterTests { diff --git a/TickAPI/TickAPI/Events/Services/EventFilter.cs b/TickAPI/TickAPI/Events/Filters/EventFilter.cs similarity index 98% rename from TickAPI/TickAPI/Events/Services/EventFilter.cs rename to TickAPI/TickAPI/Events/Filters/EventFilter.cs index f96ed48..1a4a3d5 100644 --- a/TickAPI/TickAPI/Events/Services/EventFilter.cs +++ b/TickAPI/TickAPI/Events/Filters/EventFilter.cs @@ -1,7 +1,7 @@ using TickAPI.Events.Abstractions; using TickAPI.Events.Models; -namespace TickAPI.Events.Services; +namespace TickAPI.Events.Filters; public class EventFilter : IEventFilter { diff --git a/TickAPI/TickAPI/Program.cs b/TickAPI/TickAPI/Program.cs index d98aa53..08779cd 100644 --- a/TickAPI/TickAPI/Program.cs +++ b/TickAPI/TickAPI/Program.cs @@ -92,7 +92,6 @@ // Add event services. builder.Services.AddScoped(); builder.Services.AddScoped(); -builder.Services.AddScoped(); // Add address services. builder.Services.AddScoped(); From 7ab354772143500688c27bb964c87a7be472a276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Sat, 19 Apr 2025 10:56:36 +0200 Subject: [PATCH 26/33] Resolve comments --- .../Events/Services/EventServiceTests.cs | 50 +++++++++---------- .../Abstractions/ICategoryRepository.cs | 2 - .../Abstractions/ICategoryService.cs | 2 + .../Respositories/CategoryRepository.cs | 6 --- .../Categories/Services/CategoryService.cs | 10 +++- .../TickAPI/Events/Services/EventService.cs | 38 +++++--------- 6 files changed, 48 insertions(+), 60 deletions(-) diff --git a/TickAPI/TickAPI.Tests/Events/Services/EventServiceTests.cs b/TickAPI/TickAPI.Tests/Events/Services/EventServiceTests.cs index 78d2c7c..0989a18 100644 --- a/TickAPI/TickAPI.Tests/Events/Services/EventServiceTests.cs +++ b/TickAPI/TickAPI.Tests/Events/Services/EventServiceTests.cs @@ -104,13 +104,13 @@ public async Task CreateNewEventAsync_WhenEventDataIsValid_ShouldReturnNewEvent( var dateTimeServiceMock = new Mock(); dateTimeServiceMock.Setup(m => m.GetCurrentDateTime()).Returns(new DateTime(2003, 7, 11)); - var categoryRepositoryMock = new Mock(); - categoryRepositoryMock.Setup(c => c.CheckIfCategoriesExistAsync(It.IsAny>())).Returns(Task.FromResult(true)); + var categoryServiceMock = new Mock(); + categoryServiceMock.Setup(c => c.CheckIfCategoriesExistAsync(It.IsAny>())).Returns(Task.FromResult(true)); var paginationServiceMock = new Mock(); - var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); - // act + var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, dateTimeServiceMock.Object, paginationServiceMock.Object, categoryServiceMock.Object); + // Act var result = await sut.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, categories, ticketTypes, eventStatus, organizerEmail); // Assert @@ -175,13 +175,13 @@ public async Task CreateNewEventAsync_WhenEndDateIsBeforeStartDate_ShouldReturnB var dateTimeServiceMock = new Mock(); - var categoryRepositoryMock = new Mock(); + var categoryServiceMock = new Mock(); - // act + // Act var paginationServiceMock = new Mock(); - var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); + var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, dateTimeServiceMock.Object, paginationServiceMock.Object, categoryServiceMock.Object); var res = await sut.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, categories, ticketTypes, eventStatus, organizerEmail); @@ -227,12 +227,12 @@ public async Task CreateNewEventAsync_WhenTicketTypeAvailabilityIsAfterEventsEnd var dateTimeServiceMock = new Mock(); dateTimeServiceMock.Setup(m => m.GetCurrentDateTime()).Returns(new DateTime(2025, 4, 11)); - var categoryRepositoryMock = new Mock(); + var categoryServiceMock = new Mock(); - // act + // Act var paginationServiceMock = new Mock(); - var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); + var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, dateTimeServiceMock.Object, paginationServiceMock.Object, categoryServiceMock.Object); var res = await sut.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, categories, ticketTypes, eventStatus, organizerEmail); @@ -278,12 +278,12 @@ public async Task CreateNewEventAsync_WhenStartDateIsBeforeNow_ShouldReturnBadRe var dateTimeServiceMock = new Mock(); dateTimeServiceMock.Setup(m => m.GetCurrentDateTime()).Returns(new DateTime(2025, 5, 11)); - var categoryRepositoryMock = new Mock(); + var categoryServiceMock = new Mock(); - // act + // Act var paginationServiceMock = new Mock(); - var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); + var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, dateTimeServiceMock.Object, paginationServiceMock.Object, categoryServiceMock.Object); var res = await sut.CreateNewEventAsync(name, description, startDate, endDate, minimumAge, createAddress, categories, ticketTypes, eventStatus, organizerEmail); @@ -316,7 +316,7 @@ public async Task GetOrganizerEvents_WhenPaginationSucceeds_ShouldReturnPaginate var addressServiceMock = new Mock(); var dateTimeServiceMock = new Mock(); var paginationServiceMock = new Mock(); - var categoryRepositoryMock = new Mock(); + var categoryServiceMock = new Mock(); var paginatedEvents = new PaginatedData( organizer.Events.Take(pageSize).ToList(), @@ -350,7 +350,7 @@ public async Task GetOrganizerEvents_WhenPaginationSucceeds_ShouldReturnPaginate )); var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, - dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); + dateTimeServiceMock.Object, paginationServiceMock.Object, categoryServiceMock.Object); // Act var result = await sut.GetOrganizerEventsAsync(organizer, page, pageSize); @@ -390,7 +390,7 @@ public async Task GetOrganizerEvents_WhenPaginationFails_ShouldPropagateError() var addressServiceMock = new Mock(); var dateTimeServiceMock = new Mock(); var paginationServiceMock = new Mock(); - var categoryRepositoryMock = new Mock(); + var categoryServiceMock = new Mock(); var organizerEvents = organizer.Events.AsQueryable(); eventRepositoryMock.Setup(p => p.GetEventsByOranizer(organizer)).Returns(organizerEvents); @@ -400,7 +400,7 @@ public async Task GetOrganizerEvents_WhenPaginationFails_ShouldPropagateError() .ReturnsAsync(Result>.Failure(StatusCodes.Status400BadRequest, "Invalid page number")); var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, - dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); + dateTimeServiceMock.Object, paginationServiceMock.Object, categoryServiceMock.Object); // Act var result = await sut.GetOrganizerEventsAsync(organizer, page, pageSize); @@ -429,7 +429,7 @@ public async Task GetEventsAsync_WhenPaginationSucceeds_ShouldReturnPaginatedEve var addressServiceMock = new Mock(); var dateTimeServiceMock = new Mock(); var paginationServiceMock = new Mock(); - var categoryRepositoryMock = new Mock(); + var categoryServiceMock = new Mock(); var paginatedEvents = new PaginatedData( events.Take(pageSize).ToList(), @@ -463,7 +463,7 @@ public async Task GetEventsAsync_WhenPaginationSucceeds_ShouldReturnPaginatedEve )); var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, - dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); + dateTimeServiceMock.Object, paginationServiceMock.Object, categoryServiceMock.Object); // Act var result = await sut.GetEventsAsync(page, pageSize); @@ -498,7 +498,7 @@ public async Task GetEventsAsync_WhenPaginationFails_ShouldPropagateError() var addressServiceMock = new Mock(); var dateTimeServiceMock = new Mock(); var paginationServiceMock = new Mock(); - var categoryRepositoryMock = new Mock(); + var categoryServiceMock = new Mock(); var eventsQueryable = events.AsQueryable(); eventRepositoryMock.Setup(p => p.GetEvents()).Returns(eventsQueryable); @@ -508,7 +508,7 @@ public async Task GetEventsAsync_WhenPaginationFails_ShouldPropagateError() .ReturnsAsync(Result>.Failure(StatusCodes.Status400BadRequest, "Invalid page number")); var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, - dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); + dateTimeServiceMock.Object, paginationServiceMock.Object, categoryServiceMock.Object); // Act var result = await sut.GetEventsAsync(page, pageSize); @@ -536,7 +536,7 @@ public async Task GetEventsPaginationDetailsAsync_WhenSuccessful_ShouldReturnPag var addressServiceMock = new Mock(); var dateTimeServiceMock = new Mock(); var paginationServiceMock = new Mock(); - var categoryRepositoryMock = new Mock(); + var categoryServiceMock = new Mock(); var eventsQueryable = events.AsQueryable(); eventRepositoryMock.Setup(p => p.GetEvents()).Returns(eventsQueryable); @@ -547,7 +547,7 @@ public async Task GetEventsPaginationDetailsAsync_WhenSuccessful_ShouldReturnPag .ReturnsAsync(Result.Success(paginationDetails)); var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, - dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); + dateTimeServiceMock.Object, paginationServiceMock.Object, categoryServiceMock.Object); // Act var result = await sut.GetEventsPaginationDetailsAsync(pageSize); @@ -574,7 +574,7 @@ public async Task GetEventsPaginationDetailsAsync_WhenFails_ShouldReturnError() var addressServiceMock = new Mock(); var dateTimeServiceMock = new Mock(); var paginationServiceMock = new Mock(); - var categoryRepositoryMock = new Mock(); + var categoryServiceMock = new Mock(); var eventsQueryable = events.AsQueryable(); eventRepositoryMock.Setup(p => p.GetEvents()).Returns(eventsQueryable); @@ -584,7 +584,7 @@ public async Task GetEventsPaginationDetailsAsync_WhenFails_ShouldReturnError() .ReturnsAsync(Result.Failure(StatusCodes.Status400BadRequest, "Invalid page size")); var sut = new EventService(eventRepositoryMock.Object, organizerServiceMock.Object, addressServiceMock.Object, - dateTimeServiceMock.Object, paginationServiceMock.Object, categoryRepositoryMock.Object); + dateTimeServiceMock.Object, paginationServiceMock.Object, categoryServiceMock.Object); // Act var result = await sut.GetEventsPaginationDetailsAsync(pageSize); diff --git a/TickAPI/TickAPI/Categories/Abstractions/ICategoryRepository.cs b/TickAPI/TickAPI/Categories/Abstractions/ICategoryRepository.cs index 9e6e598..c7d1fc3 100644 --- a/TickAPI/TickAPI/Categories/Abstractions/ICategoryRepository.cs +++ b/TickAPI/TickAPI/Categories/Abstractions/ICategoryRepository.cs @@ -8,6 +8,4 @@ public interface ICategoryRepository public IQueryable GetCategories(); public Task> GetCategoryByNameAsync(string categoryName); public Task AddNewCategoryAsync(Category category); - - public Task CheckIfCategoriesExistAsync(List categories); } \ No newline at end of file diff --git a/TickAPI/TickAPI/Categories/Abstractions/ICategoryService.cs b/TickAPI/TickAPI/Categories/Abstractions/ICategoryService.cs index 0e33bf0..8560738 100644 --- a/TickAPI/TickAPI/Categories/Abstractions/ICategoryService.cs +++ b/TickAPI/TickAPI/Categories/Abstractions/ICategoryService.cs @@ -10,4 +10,6 @@ public interface ICategoryService public Task> GetCategoryByNameAsync(string categoryName); public Task>> GetCategoriesResponsesAsync(int pageSize, int page); public Task> CreateNewCategoryAsync(string categoryName); + + public Task CheckIfCategoriesExistAsync(IEnumerable categories); } \ No newline at end of file diff --git a/TickAPI/TickAPI/Categories/Respositories/CategoryRepository.cs b/TickAPI/TickAPI/Categories/Respositories/CategoryRepository.cs index 0f920ac..e1dcdb2 100644 --- a/TickAPI/TickAPI/Categories/Respositories/CategoryRepository.cs +++ b/TickAPI/TickAPI/Categories/Respositories/CategoryRepository.cs @@ -31,12 +31,6 @@ public async Task> GetCategoryByNameAsync(string categoryName) return Result.Success(category); } - public async Task CheckIfCategoriesExistAsync(List categories) - { - var dbCategories = await _tickApiDbContext.Categories.ToListAsync(); - return categories.All(c => dbCategories.Any(cdb => cdb.Name == c.Name)); - } - public async Task AddNewCategoryAsync(Category category) { _tickApiDbContext.Categories.Add(category); diff --git a/TickAPI/TickAPI/Categories/Services/CategoryService.cs b/TickAPI/TickAPI/Categories/Services/CategoryService.cs index 929c99e..e30dafc 100644 --- a/TickAPI/TickAPI/Categories/Services/CategoryService.cs +++ b/TickAPI/TickAPI/Categories/Services/CategoryService.cs @@ -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; @@ -55,4 +56,11 @@ public async Task> CreateNewCategoryAsync(string categoryName) await _categoryRepository.AddNewCategoryAsync(category); return Result.Success(category); } + + public async Task CheckIfCategoriesExistAsync(IEnumerable categories) + { + var dbCategories = _categoryRepository.GetCategories(); + int count = await dbCategories.Where(cdb => categories.Any(c => c.Name == cdb.Name)).CountAsync(); + return count == categories.Count(); + } } \ No newline at end of file diff --git a/TickAPI/TickAPI/Events/Services/EventService.cs b/TickAPI/TickAPI/Events/Services/EventService.cs index e258c92..117c7eb 100644 --- a/TickAPI/TickAPI/Events/Services/EventService.cs +++ b/TickAPI/TickAPI/Events/Services/EventService.cs @@ -24,16 +24,16 @@ public class EventService : IEventService private readonly IAddressService _addressService; private readonly IDateTimeService _dateTimeService; private readonly IPaginationService _paginationService; - private readonly ICategoryRepository _categoryRepository; + private readonly ICategoryService _categoryService; - public EventService(IEventRepository eventRepository, IOrganizerService organizerService, IAddressService addressService, IDateTimeService dateTimeService, IPaginationService paginationService, ICategoryRepository categoryRepository) + public EventService(IEventRepository eventRepository, IOrganizerService organizerService, IAddressService addressService, IDateTimeService dateTimeService, IPaginationService paginationService, ICategoryService categoryService) { _eventRepository = eventRepository; _organizerService = organizerService; _addressService = addressService; _dateTimeService = dateTimeService; _paginationService = paginationService; - _categoryRepository = categoryRepository; + _categoryService = categoryService; } public async Task> CreateNewEventAsync(string name, string description, DateTime startDate, DateTime endDate, @@ -51,45 +51,31 @@ public async Task> CreateNewEventAsync(string name, string descri if (startDate < _dateTimeService.GetCurrentDateTime()) return Result.Failure(StatusCodes.Status400BadRequest, "Start date is in the past"); - foreach (var t in ticketTypes) + if (ticketTypes.Any(t => t.AvailableFrom > endDate)) { - if (t.AvailableFrom > endDate) - { - return Result.Failure(StatusCodes.Status400BadRequest, "Tickets can't be available after the event is over"); - } + return Result.Failure(StatusCodes.Status400BadRequest, "Tickets can't be available after the event is over"); } var address = await _addressService.GetOrCreateAddressAsync(createAddress); - var categoriesConverted = new List(); - - foreach (var c in categories) - { - categoriesConverted.Add(new Category - { - Name = c.CategoryName - }); - } + var categoriesConverted = categories.Select(c => new Category { Name = c.CategoryName }).ToList(); - var categoriesExist = await _categoryRepository.CheckIfCategoriesExistAsync(categoriesConverted); + var categoriesExist = await _categoryService.CheckIfCategoriesExistAsync(categoriesConverted); if (!categoriesExist) { - return Result.Failure(StatusCodes.Status403Forbidden, "Category does not exist"); + return Result.Failure(StatusCodes.Status400BadRequest, "Category does not exist"); } - var ticketTypesConverted = new List(); - foreach (var t in ticketTypes) - { - ticketTypesConverted.Add(new TicketType + 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, From 2515dffe4be446edc51ac66aaca54b201b2bac81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Sat, 19 Apr 2025 15:58:58 +0200 Subject: [PATCH 27/33] Add deploy yml --- .github/workflows/deployapi.yml | 67 +++++++++++++++++++++++++++++++++ TickAPI/TickAPI/TickAPI.csproj | 7 +++- 2 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/deployapi.yml diff --git a/.github/workflows/deployapi.yml b/.github/workflows/deployapi.yml new file mode 100644 index 0000000..1c63575 --- /dev/null +++ b/.github/workflows/deployapi.yml @@ -0,0 +1,67 @@ +# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy +# More GitHub Actions for Azure: https://github.com/Azure/actions + +name: Build and deploy ASP.Net Core app to Azure Web App - resellio + +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + build: + runs-on: windows-latest + permissions: + contents: read #This is required for actions/checkout + + steps: + - uses: actions/checkout@v4 + + - name: Set up .NET Core + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '9.x' + + - name: Build with dotnet + run: dotnet build TickAPI/TickAPI/TickAPI.csproj --configuration Release + + - name: dotnet publish + run: dotnet publish TickAPI/TickAPI/TickAPI.csproj -c Release -o "${{env.DOTNET_ROOT}}/myapp" + + - name: Upload artifact for deployment job + uses: actions/upload-artifact@v4 + with: + name: .net-app + path: ${{env.DOTNET_ROOT}}/myapp + + deploy: + runs-on: windows-latest + needs: build + environment: + name: 'Production' + url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} + permissions: + id-token: write #This is required for requesting the JWT + contents: read #This is required for actions/checkout + + steps: + - name: Download artifact from build job + uses: actions/download-artifact@v4 + with: + name: .net-app + + - name: Login to Azure + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_F22C931708554F8B83EE4F83C4FED407 }} + tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_6CDAC678ACD94858BF3421F606456B8B }} + subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_CA368EC8EA37446E96D5DF5F42B650EA }} + + - name: Deploy to Azure Web App + id: deploy-to-webapp + uses: azure/webapps-deploy@v3 + with: + app-name: 'resellio' + slot-name: 'Production' + package: . diff --git a/TickAPI/TickAPI/TickAPI.csproj b/TickAPI/TickAPI/TickAPI.csproj index 1e131f6..e1b2c68 100644 --- a/TickAPI/TickAPI/TickAPI.csproj +++ b/TickAPI/TickAPI/TickAPI.csproj @@ -1,17 +1,20 @@ - + net9.0 enable enable - + 9eaa86f9-f226-40d9-82e5-ca6c514f791c + + + all From 0c743b01e26884a3168d0b6c0ef7bf7a00cbc3ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Sat, 19 Apr 2025 16:05:03 +0200 Subject: [PATCH 28/33] Trigger action --- .../Customers/Controllers/CustomerControllerTests.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TickAPI/TickAPI.Tests/Customers/Controllers/CustomerControllerTests.cs b/TickAPI/TickAPI.Tests/Customers/Controllers/CustomerControllerTests.cs index 8e9eadd..b06dbf1 100644 --- a/TickAPI/TickAPI.Tests/Customers/Controllers/CustomerControllerTests.cs +++ b/TickAPI/TickAPI.Tests/Customers/Controllers/CustomerControllerTests.cs @@ -20,6 +20,8 @@ public class CustomerControllerTests public async Task GoogleLogin_WhenAuthSuccessAndCustomerExists_ShouldReturnToken() { // Arrange + + //c const string email = "existing@test.com"; const string accessToken = "valid-google-token"; const string jwtToken = "valid-jwt-token"; From 9332cf6a55f0fabed6f725105063c8a1e163cb48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Sat, 19 Apr 2025 16:09:07 +0200 Subject: [PATCH 29/33] Test yml on fest/actions --- .github/workflows/deployapi.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deployapi.yml b/.github/workflows/deployapi.yml index 1c63575..9d03751 100644 --- a/.github/workflows/deployapi.yml +++ b/.github/workflows/deployapi.yml @@ -1,12 +1,12 @@ # Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy # More GitHub Actions for Azure: https://github.com/Azure/actions -name: Build and deploy ASP.Net Core app to Azure Web App - resellio +name: Build and deploy Resellio Backend on: push: branches: - - main + - feat/actions workflow_dispatch: jobs: From accd4fb9dc217416ca21b6f0ea5f1b0cf906f75a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Sat, 19 Apr 2025 16:15:18 +0200 Subject: [PATCH 30/33] Deploy form main --- .github/workflows/deployapi.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deployapi.yml b/.github/workflows/deployapi.yml index 9d03751..ce14923 100644 --- a/.github/workflows/deployapi.yml +++ b/.github/workflows/deployapi.yml @@ -6,7 +6,7 @@ name: Build and deploy Resellio Backend on: push: branches: - - feat/actions + - main workflow_dispatch: jobs: From 3568f60e0370e1c5f1c8c980f9b1d8d470ecf4e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Sat, 19 Apr 2025 16:23:23 +0200 Subject: [PATCH 31/33] Update CustomersControllerTests.cs --- .../Customers/Controllers/CustomersControllerTests.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/TickAPI/TickAPI.Tests/Customers/Controllers/CustomersControllerTests.cs b/TickAPI/TickAPI.Tests/Customers/Controllers/CustomersControllerTests.cs index b9aad91..fe8999a 100644 --- a/TickAPI/TickAPI.Tests/Customers/Controllers/CustomersControllerTests.cs +++ b/TickAPI/TickAPI.Tests/Customers/Controllers/CustomersControllerTests.cs @@ -20,8 +20,6 @@ public class CustomersControllerTests public async Task GoogleLogin_WhenAuthSuccessAndCustomerExists_ShouldReturnToken() { // Arrange - - //c const string email = "existing@test.com"; const string accessToken = "valid-google-token"; const string jwtToken = "valid-jwt-token"; @@ -196,4 +194,4 @@ public async Task AboutMe_WithMissingEmailClaim_ShouldReturnBadRequest() Assert.Equal(StatusCodes.Status400BadRequest, objectResult.StatusCode); Assert.Equal("missing email claim", objectResult.Value); } -} \ No newline at end of file +} From 6cf62c8434c243cb438dbac0ba84d74ee28abcc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Sat, 19 Apr 2025 16:30:50 +0200 Subject: [PATCH 32/33] Delete app configuration rubbish --- TickAPI/TickAPI/TickAPI.csproj | 3 --- 1 file changed, 3 deletions(-) diff --git a/TickAPI/TickAPI/TickAPI.csproj b/TickAPI/TickAPI/TickAPI.csproj index e1b2c68..26ae670 100644 --- a/TickAPI/TickAPI/TickAPI.csproj +++ b/TickAPI/TickAPI/TickAPI.csproj @@ -4,17 +4,14 @@ net9.0 enable enable - 9eaa86f9-f226-40d9-82e5-ca6c514f791c - - all From 129936ecfb37f175ed63e4092022540c4905491c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Sat, 19 Apr 2025 16:39:50 +0200 Subject: [PATCH 33/33] Update TickAPI.csproj Add tab for @kTrzcinskii --- TickAPI/TickAPI/TickAPI.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TickAPI/TickAPI/TickAPI.csproj b/TickAPI/TickAPI/TickAPI.csproj index 26ae670..aeff0ec 100644 --- a/TickAPI/TickAPI/TickAPI.csproj +++ b/TickAPI/TickAPI/TickAPI.csproj @@ -4,7 +4,7 @@ net9.0 enable enable - +