diff --git a/StudHub.Server.sln b/StudHub.Server.sln index ec49472..f1e5bae 100644 --- a/StudHub.Server.sln +++ b/StudHub.Server.sln @@ -10,6 +10,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Platform.API", "src\Platfor EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Admin.API", "src\Admin.API\Admin.API.csproj", "{781F6E4E-FC3B-46E4-895A-F27A4310CF42}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unit", "test\Unit\Unit.csproj", "{3558A138-C00A-4857-93E5-3ECCB5CD873C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -36,5 +38,9 @@ Global {781F6E4E-FC3B-46E4-895A-F27A4310CF42}.Debug|Any CPU.Build.0 = Debug|Any CPU {781F6E4E-FC3B-46E4-895A-F27A4310CF42}.Release|Any CPU.ActiveCfg = Release|Any CPU {781F6E4E-FC3B-46E4-895A-F27A4310CF42}.Release|Any CPU.Build.0 = Release|Any CPU + {3558A138-C00A-4857-93E5-3ECCB5CD873C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3558A138-C00A-4857-93E5-3ECCB5CD873C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3558A138-C00A-4857-93E5-3ECCB5CD873C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3558A138-C00A-4857-93E5-3ECCB5CD873C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/src/Platform.API/appsettings.json b/src/Platform.API/appsettings.json index 9648d0a..876b1c3 100644 --- a/src/Platform.API/appsettings.json +++ b/src/Platform.API/appsettings.json @@ -20,9 +20,5 @@ ] }, "Domain": ".setka-rtu.ru", - "AllowedHosts": "*", - "JWTKey": "9>I4=o8{AG\\Nh{`I7m*={tP:Gs)dsXxNw.Hj92]dQSO", - "ConnectionStrings": { - "Default": "Host=31.128.38.159;Port=5432;User ID=admin-setka;Password=P1{Hg?:(~jLfDNrp!W9QkF?bO;Database=SetkaDB" - } + "AllowedHosts": "*" } \ No newline at end of file diff --git a/test/Unit/ClubCreationRequestsServiceTests.cs b/test/Unit/ClubCreationRequestsServiceTests.cs new file mode 100644 index 0000000..fc6e0ae --- /dev/null +++ b/test/Unit/ClubCreationRequestsServiceTests.cs @@ -0,0 +1,257 @@ +using System.ComponentModel.DataAnnotations; +using AutoMapper; +using Moq; +using Serilog; +using Domain.Entities.Admin; +using Domain.Entities.Club; +using Application.DTO; +using Application.Exceptions; +using Application.Interfaces.Repositories.Admin; +using Application.Interfaces.Repositories.Club; +using Application.Services; + +namespace Unit; + +public class ClubCreationRequestsServiceTests +{ + private readonly Mock _requestsRepoMock; + private readonly Mock _clubsRepoMock; + private readonly Mock _loggerMock; + private readonly Mock _mapperMock; + private readonly ClubCreationRequestsService _clubCreationRequestsService; + public ClubCreationRequestsServiceTests() + { + _requestsRepoMock = new Mock(); + _clubsRepoMock = new Mock(); + _loggerMock = new Mock(); + _mapperMock = new Mock(); + _clubCreationRequestsService = new ClubCreationRequestsService(_requestsRepoMock.Object, _clubsRepoMock.Object, + _mapperMock.Object, _loggerMock.Object); + } + #region CreateRequest + [Fact] + public void CreateRequest_WithValidData_Succeeds() + { + var clubCreationRequest = new ClubCreationRequestDTO + { + ClubName = "Новый клуб", + Comment = "Новый клуб для тестирования функциональности", + PersonId = 0, + ImageId = 0, + BannerId = 0, + ClubAbout = "Описание клуба для создания" + }; + var context = new ValidationContext(clubCreationRequest); + var results = new List(); + + var isValid = Validator.TryValidateObject(clubCreationRequest, context, results, true); + + Assert.True(isValid); + } + + [Fact] + public void CreateRequest_WithEmptyClubName_ValidationFails() + { + var clubCreationRequest = new ClubCreationRequestDTO + { + Comment = "Новый клуб для тестирования функциональности", + PersonId = 0, + ImageId = 0, + BannerId = 0, + ClubAbout = new string('0', 100) + }; + var context = new ValidationContext(clubCreationRequest); + var results = new List(); + + var isValid = Validator.TryValidateObject(clubCreationRequest, context, results, true); + + Assert.False(isValid); + Assert.Contains(results, r => r.MemberNames.Contains("ClubName") && r.ErrorMessage!.Contains("required")); + } + + [Fact] + public void CreateRequest_WithLongClubName_ValidationFails() + { + var clubCreationRequest = new ClubCreationRequestDTO + { + ClubName = new string('0', 64), + Comment = "Новый клуб для тестирования функциональности", + PersonId = 0, + ImageId = 0, + BannerId = 0, + ClubAbout = new string('0', 100) + }; + var context = new ValidationContext(clubCreationRequest); + var results = new List(); + + var isValid = Validator.TryValidateObject(clubCreationRequest, context, results, true); + + Assert.False(isValid); + Assert.Contains(results, r => r.MemberNames.Contains("ClubName") && r.ErrorMessage!.Contains("maximum length")); + } + + [Fact] + public void CreateRequest_WithEmptyImageId_ValidationFails() + { + var clubCreationRequest = new ClubCreationRequestDTO + { + ClubName = "Новый клуб", + Comment = "Новый клуб для тестирования функциональности", + PersonId = 0 + }; + var context = new ValidationContext(clubCreationRequest); + var results = new List(); + + var isValid = Validator.TryValidateObject(clubCreationRequest, context, results, true); + + Assert.False(isValid); + Assert.Contains(results, r => r.MemberNames.Contains("ImageId") && r.ErrorMessage!.Contains("required")); + } + + [Fact] + public void CreateRequest_WithEmptyPersonId_ValidationFails() + { + var clubCreationRequest = new ClubCreationRequestDTO + { + ClubName = "Новый клуб", + Comment = "Новый клуб для тестирования функциональности", + ImageId = 0 + }; + var context = new ValidationContext(clubCreationRequest); + var results = new List(); + + var isValid = Validator.TryValidateObject(clubCreationRequest, context, results, true); + + Assert.False(isValid); + Assert.Contains(results, r => r.MemberNames.Contains("PersonId") && r.ErrorMessage!.Contains("required")); + } + + [Fact] + public void CreateRequest_WithLongClubAbout_ValidationFails() + { + var clubCreationRequest = new ClubCreationRequestDTO + { + ClubName = "Новый клуб", + Comment = "Новый клуб для тестирования функциональности", + PersonId = 0, + ImageId = 0, + BannerId = 0, + ClubAbout = new string('0', 256) + }; + var context = new ValidationContext(clubCreationRequest); + var results = new List(); + + var isValid = Validator.TryValidateObject(clubCreationRequest, context, results, true); + + Assert.False(isValid); + Assert.Contains(results, r => r.MemberNames.Contains("ClubAbout") && r.ErrorMessage!.Contains("maximum length")); + } + + [Fact] + public void CreateRequest_WithEmptyComment_ValidationFails() + { + var clubCreationRequest = new ClubCreationRequestDTO + { + ClubName = "Новый клуб", + Comment = "", + PersonId = 0 + }; + var context = new ValidationContext(clubCreationRequest); + var results = new List(); + + var isValid = Validator.TryValidateObject(clubCreationRequest, context, results, true); + + Assert.False(isValid); + Assert.Contains(results, r => r.MemberNames.Contains("Comment") && r.ErrorMessage!.Contains("required")); + } + + [Fact] + public void CreateRequest_WithLongComment_ValidationFails() + { + var clubCreationRequest = new ClubCreationRequestDTO + { + ClubName = "Новый клуб", + Comment = new string('0', 1001), + PersonId = 0 + }; + var context = new ValidationContext(clubCreationRequest); + var results = new List(); + + var isValid = Validator.TryValidateObject(clubCreationRequest, context, results, true); + + Assert.False(isValid); + Assert.Contains(results, r => r.MemberNames.Contains("Comment") && r.ErrorMessage!.Contains("maximum length")); + } + [Fact] + public async Task AcceptRequest_WhenRequestNotFound_ThrowsNotFoundException() + { + var requestId = 1; + _requestsRepoMock + .Setup(r => r.GetByIdAsync(requestId)) + .ReturnsAsync((ClubCreationRequest)null); + + await Assert.ThrowsAsync(() => _clubCreationRequestsService.AcceptRequest(requestId)); + } + + [Fact] + public async Task AcceptRequest_WhenRequestIsNotActive_ThrowsInvalidOperationException() + { + var requestId = 1; + var inactiveRequest = new ClubCreationRequest { IsActive = false }; + _requestsRepoMock + .Setup(r => r.GetByIdAsync(requestId)) + .ReturnsAsync(inactiveRequest); + + var exception = await Assert.ThrowsAsync( + () => _clubCreationRequestsService.AcceptRequest(requestId)); + Assert.Equal("Заявка на создание клуба уже была рассмотрена", exception.Message); + } + + [Fact] + public async Task AcceptRequest_WhenValidRequest_CreatesClubAndUpdatesRequest() + { + var requestId = 1; + var activeRequest = new ClubCreationRequest + { + Id = requestId, + ClubName = "Test Club", + ClubAbout = "About club", + ImageId = 1, + BannerId = 2, + PersonId = 3, + IsActive = true + }; + + _requestsRepoMock + .Setup(r => r.GetByIdAsync(requestId)) + .ReturnsAsync(activeRequest); + + ClubModel createdClub = null; + _clubsRepoMock + .Setup(r => r.CreateAsync(It.IsAny())) + .Callback(club => createdClub = club) + .Returns(Task.CompletedTask); + + _requestsRepoMock + .Setup(r => r.UpdateAsync(activeRequest)) + .Returns(Task.CompletedTask); + + await _clubCreationRequestsService.AcceptRequest(requestId); + + _clubsRepoMock.Verify(r => r.CreateAsync(It.IsAny()), Times.Once); + _requestsRepoMock.Verify(r => r.UpdateAsync(activeRequest), Times.Once); + + Assert.NotNull(createdClub); + Assert.Equal(activeRequest.ClubName, createdClub.Name); + Assert.Equal(activeRequest.ClubAbout, createdClub.About); + Assert.Equal(activeRequest.ImageId, createdClub.ImageId); + Assert.Equal(activeRequest.BannerId, createdClub.BannerId); + Assert.Equal(activeRequest.PersonId, createdClub.OwnerId); + Assert.False(activeRequest.IsActive); + + _loggerMock.Verify(l => l.Information( + "Заявка на создание клуба с Id ({RequestId}) одобрена", requestId), + Times.Once); + } + #endregion +} \ No newline at end of file diff --git a/test/Unit/Unit.csproj b/test/Unit/Unit.csproj new file mode 100644 index 0000000..3285fca --- /dev/null +++ b/test/Unit/Unit.csproj @@ -0,0 +1,26 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + +