From a05cc8e910e6c0f44357027f4262961972b612db Mon Sep 17 00:00:00 2001 From: BodyaAP <53657043+BodyaAP@users.noreply.github.com> Date: Wed, 13 May 2026 07:54:43 +0300 Subject: [PATCH 1/5] Added tests for MediatR/Media/Art --- .gitignore | 4 +- .../StreetcodeDbContextModelSnapshot.cs | 2 +- Streetcode/Streetcode.WebApi/Program.cs | 2 +- .../Streetcode.WebApi/appsettings.Local.json | 11 ---- Streetcode/Streetcode.WebApi/appsettings.json | 55 ------------------- Streetcode/Streetcode.XUnitTest/stylecop.json | 14 +++++ build/_build.csproj.DotSettings | 5 +- 7 files changed, 23 insertions(+), 70 deletions(-) delete mode 100644 Streetcode/Streetcode.WebApi/appsettings.Local.json delete mode 100644 Streetcode/Streetcode.WebApi/appsettings.json create mode 100644 Streetcode/Streetcode.XUnitTest/stylecop.json diff --git a/.gitignore b/.gitignore index f4848c0..fc4c4df 100644 --- a/.gitignore +++ b/.gitignore @@ -344,4 +344,6 @@ healthchecksdb # BlobStorage BlobStorageFolder/ -BlobStorageTestFolder/ \ No newline at end of file +BlobStorageTestFolder/ +/Streetcode/Streetcode.WebApi/appsettings.json +/Streetcode/Streetcode.WebApi/appsettings.Local.json diff --git a/Streetcode/Streetcode.DAL/Persistence/Migrations/StreetcodeDbContextModelSnapshot.cs b/Streetcode/Streetcode.DAL/Persistence/Migrations/StreetcodeDbContextModelSnapshot.cs index 84f1c0e..a5092ca 100644 --- a/Streetcode/Streetcode.DAL/Persistence/Migrations/StreetcodeDbContextModelSnapshot.cs +++ b/Streetcode/Streetcode.DAL/Persistence/Migrations/StreetcodeDbContextModelSnapshot.cs @@ -842,7 +842,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("HistoricalContextId"); - b.ToTable("HistoricalContextsTimelines"); + b.ToTable("HistoricalContextsTimelines", (string)null); }); modelBuilder.Entity("Streetcode.DAL.Entities.Timeline.TimelineItem", b => diff --git a/Streetcode/Streetcode.WebApi/Program.cs b/Streetcode/Streetcode.WebApi/Program.cs index 02523a8..d0ce7a8 100644 --- a/Streetcode/Streetcode.WebApi/Program.cs +++ b/Streetcode/Streetcode.WebApi/Program.cs @@ -27,7 +27,7 @@ await app.ApplyMigrations(); -// await app.SeedDataAsync(); // uncomment for seeding data in local +await app.SeedDataAsync(); // uncomment for seeding data in local app.UseCors(); app.UseHttpsRedirection(); app.UseRouting(); diff --git a/Streetcode/Streetcode.WebApi/appsettings.Local.json b/Streetcode/Streetcode.WebApi/appsettings.Local.json deleted file mode 100644 index 14b4447..0000000 --- a/Streetcode/Streetcode.WebApi/appsettings.Local.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "ConnectionStrings": { - "DefaultConnection": "Server=127.0.0.1;Database=StreetcodeDb;User Id=sa;Password=Admin@1234;MultipleActiveResultSets=true" - }, - "CORS": { - "AllowedOrigins": [ "http://localhost:3000" ], - "AllowedHeaders": [ "*" ], - "AllowedMethods": [ "*" ], - "PreflightMaxAge": 1 - } -} diff --git a/Streetcode/Streetcode.WebApi/appsettings.json b/Streetcode/Streetcode.WebApi/appsettings.json deleted file mode 100644 index 7e1e684..0000000 --- a/Streetcode/Streetcode.WebApi/appsettings.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "ConnectionStrings": { - "DefaultConnection": "Server=127.0.0.1;Database=StreetcodeDb;User Id=sa;Password=Admin@1234;MultipleActiveResultSets=true" - }, - "EmailConfiguration": { - "From": "streetcodefeedback@gmail.com", - "To": "streetcodeua@gmail.com", - "SmtpServer": "smtp.gmail.com", - "Port": 465, - "Username": "streetcodefeedback@gmail.com" - }, - "Serilog": { - "Using": [], - "MinimumLevel": { - "Default": "Information", - "Microsoft": "Warning", - "System": "Warning" - }, - "Enrich": [ - "FromLogContext", - "WithMachineName", - "WithProcessId", - "WithThreadId" - ], - "WriteTo": [ - { - "Name": "Console" - } - ] - }, - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "AllowedHosts": "*", - "Blob": { - "BlobStoreKey": "SlavaKasterovSuperGoodInshalaKey", - "BlobStorePath": "../../BlobStorageFolder/" - }, - "Payment": { - "Token": "BombasticTokenForMonobank" - }, - "Instagram": { - "InstagramID": "NiceIdForInstagram", - "InstagramToken": "SuperNiceTokenForInstagram" - }, - "CORS": { - "AllowedOrigins": [], - "AllowedHeaders": [], - "AllowedMethods": [], - "PreflightMaxAge": 1 - } -} diff --git a/Streetcode/Streetcode.XUnitTest/stylecop.json b/Streetcode/Streetcode.XUnitTest/stylecop.json new file mode 100644 index 0000000..42fb1f8 --- /dev/null +++ b/Streetcode/Streetcode.XUnitTest/stylecop.json @@ -0,0 +1,14 @@ +{ + // ACTION REQUIRED: This file was automatically added to your project, but it + // will not take effect until additional steps are taken to enable it. See the + // following page for additional information: + // + // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md + + "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", + "settings": { + "documentationRules": { + "companyName": "PlaceholderCompany" + } + } +} diff --git a/build/_build.csproj.DotSettings b/build/_build.csproj.DotSettings index 7bc2848..0306022 100644 --- a/build/_build.csproj.DotSettings +++ b/build/_build.csproj.DotSettings @@ -16,6 +16,8 @@ False <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> + <Policy><Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></Policy> + <Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static fields (private)"><ElementKinds><Kind Name="FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></Policy> True True True @@ -24,4 +26,5 @@ True True True - True + True + True From 50dd8f88fae21386efa1553a97699f0f43a4d499 Mon Sep 17 00:00:00 2001 From: BodyaAP <53657043+BodyaAP@users.noreply.github.com> Date: Wed, 13 May 2026 07:55:25 +0300 Subject: [PATCH 2/5] Added tests for MediatR/Media/Art --- .../Art/GetAll/GetAllArtsHandlerTests.cs | 111 +++++++++++++++ .../Art/GetById/GetArtByIdHandlerTests.cs | 117 ++++++++++++++++ .../GetArtByStreetcodeIdHandlerTests.cs | 131 ++++++++++++++++++ 3 files changed, 359 insertions(+) create mode 100644 Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetAll/GetAllArtsHandlerTests.cs create mode 100644 Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetById/GetArtByIdHandlerTests.cs create mode 100644 Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetByStreetcodeId/GetArtByStreetcodeIdHandlerTests.cs diff --git a/Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetAll/GetAllArtsHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetAll/GetAllArtsHandlerTests.cs new file mode 100644 index 0000000..21174cf --- /dev/null +++ b/Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetAll/GetAllArtsHandlerTests.cs @@ -0,0 +1,111 @@ +using AutoMapper; +using FluentResults; +using Microsoft.EntityFrameworkCore.Query; +using Moq; +using Repositories.Interfaces; +using Streetcode.BLL.DTO.Media.Art; +using Streetcode.BLL.Interfaces.Logging; +using Streetcode.BLL.MediatR.Media.Art.GetAll; +using Streetcode.DAL.Entities.Media.Images; +using Streetcode.DAL.Repositories.Interfaces.Base; +using System.Linq.Expressions; +using Xunit; + +namespace Streetcode.XUnitTest.BLL.MediatR.Media.Art.GetAll; + +/// +/// Tests for GetAllArtsHandler. +/// +public class GetAllArtsHandlerTests +{ + private GetAllArtsHandler handler; + + private Mock mockMapper; + private Mock mockRepository; + private Mock mockArtRepository; + private Mock mockLoggerService; + + private IMapper mapper; + + /// + /// Initializes a new instance of the class. + /// + public GetAllArtsHandlerTests() + { + this.mockMapper = new Mock(); + this.mockRepository = new Mock(); + this.mockArtRepository = new Mock(); + this.mockLoggerService = new Mock(); + + this.mockRepository + .Setup(r => r.ArtRepository) + .Returns(this.mockArtRepository.Object); + + this.mapper = new MapperConfiguration(cfg => + { + cfg.CreateMap(); + }).CreateMapper(); + + this.handler = new GetAllArtsHandler( + this.mockRepository.Object, + this.mapper, + this.mockLoggerService.Object); + } + + /// + /// Method Handel returns all Arts, if they are. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task Handle_ArtsNotEmpty_ReturnAllArts() + { + var query = new GetAllArtsQuery(); + + int expectedCount = 1; + + var arts = new List() + { + new DAL.Entities.Media.Images.Art() + { + Id = 1, + Description = "Description art 1", + ImageId = 1, + Title = "Title art 1", + }, + }; + + this.mockArtRepository + .Setup(r => r.GetAllAsync( + It.IsAny>>(), + It.IsAny, + IIncludableQueryable>>())) + .ReturnsAsync(arts); + + var result = await this.handler.Handle(query, CancellationToken.None); + + Assert.Equal(expectedCount, result.Value.Count()); + } + + /// + /// Method Handle return error message, if Arts do not exist. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task Handle_ArtsIsEmpty_ReturnErrorMessage() + { + var query = new GetAllArtsQuery(); + + var expectedError = new Error($"Cannot find any arts"); + + this.mockArtRepository + .Setup(r => r.GetAllAsync( + It.IsAny>>(), + It.IsAny, + IIncludableQueryable>>())) + .ReturnsAsync((List?)null); + + var result = await this.handler.Handle(query, CancellationToken.None); + + Assert.Equal(expectedError.Message, result.Errors.First().Message); + } +} diff --git a/Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetById/GetArtByIdHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetById/GetArtByIdHandlerTests.cs new file mode 100644 index 0000000..1681ff7 --- /dev/null +++ b/Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetById/GetArtByIdHandlerTests.cs @@ -0,0 +1,117 @@ +using AutoMapper; +using Microsoft.EntityFrameworkCore.Query; +using Moq; +using Org.BouncyCastle.Asn1.Ocsp; +using Repositories.Interfaces; +using Streetcode.BLL.DTO.Media.Art; +using Streetcode.BLL.Interfaces.Logging; +using Streetcode.BLL.MediatR.Media.Art.GetById; +using Streetcode.DAL.Repositories.Interfaces.Base; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace Streetcode.XUnitTest.BLL.MediatR.Media.Art.GetById +{ + /// + /// Checking class GetArtByIdHandler. + /// + public class GetArtByIdHandlerTests + { + private GetArtByIdHandler handler; + + private Mock mockMapper; + private Mock mockRepository; + private Mock mockArtRepository; + private Mock mockLoggerService; + + /// + /// Initializes a new instance of the class. + /// + public GetArtByIdHandlerTests() + { + this.mockMapper = new Mock(); + this.mockArtRepository = new Mock(); + this.mockRepository = new Mock(); + this.mockLoggerService = new Mock(); + + this.mockRepository + .Setup(r => r.ArtRepository) + .Returns(this.mockArtRepository.Object); + + this.handler = new GetArtByIdHandler( + this.mockRepository.Object, + this.mockMapper.Object, + this.mockLoggerService.Object); + } + + /// + /// Method returns correct art, if entered valid id. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task Handle_ValidId_ReturnArt() + { + var query = new GetArtByIdQuery(1); + + var art = new DAL.Entities.Media.Images.Art() + { + Id = 1, + Description = "Description art 1", + ImageId = 1, + Title = "Title art 1", + }; + + var artDTO = new ArtDTO() + { + Id = 1, + Description = "Description art 1", + ImageId = 1, + Title = "Title art 1", + }; + + this.mockArtRepository + .Setup(r => r.GetFirstOrDefaultAsync( + It.IsAny>>(), + It.IsAny, + IIncludableQueryable>>())) + .ReturnsAsync(art); + + this.mockMapper + .Setup(m => m.Map( + It.IsAny())) + .Returns(artDTO); + + var result = await this.handler.Handle(query, CancellationToken.None); + + Assert.Equal(artDTO.Id, result.Value.Id); + } + + /// + /// Method returns error message, if entered not valid id. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task Handle_NotValidId_ReturnError() + { + var query = new GetArtByIdQuery(2); + + string expectedErrorMsg = $"Cannot find an art with corresponding id: {query.Id}"; + + this.mockArtRepository + .Setup(r => r.GetFirstOrDefaultAsync( + It.IsAny>>(), + It.IsAny, + IIncludableQueryable>>())) + .ReturnsAsync((DAL.Entities.Media.Images.Art?)null); + + var result = await this.handler.Handle(query, CancellationToken.None); + + Assert.Equal(expectedErrorMsg, result.Errors.First().Message); + } + } +} diff --git a/Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetByStreetcodeId/GetArtByStreetcodeIdHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetByStreetcodeId/GetArtByStreetcodeIdHandlerTests.cs new file mode 100644 index 0000000..4605e58 --- /dev/null +++ b/Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetByStreetcodeId/GetArtByStreetcodeIdHandlerTests.cs @@ -0,0 +1,131 @@ +using AutoMapper; +using Castle.Core.Logging; +using Microsoft.EntityFrameworkCore.Query; +using Moq; +using Org.BouncyCastle.Asn1.Ocsp; +using Repositories.Interfaces; +using Streetcode.BLL.DTO.Media.Art; +using Streetcode.BLL.Interfaces.BlobStorage; +using Streetcode.BLL.Interfaces.Logging; +using Streetcode.BLL.MediatR.Media.Art.GetByStreetcodeId; +using Streetcode.DAL.Entities.Media.Images; +using Streetcode.DAL.Entities.Streetcode; +using Streetcode.DAL.Repositories.Interfaces.Base; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace Streetcode.XUnitTest.BLL.MediatR.Media.Art.GetByStreetcodeId +{ + /// + /// Checking class GetArtByStreetcodeIdHandler. + /// + public class GetArtByStreetcodeIdHandlerTests + { + private GetArtsByStreetcodeIdHandler handler; + + private Mock mockRepository; + private Mock mockMapper; + private Mock mockBlobService; + private Mock mockLoggerService; + private Mock mockArtRepository; + + private IMapper mapper; + + /// + /// Initializes a new instance of the class. + /// + public GetArtByStreetcodeIdHandlerTests() + { + this.mockRepository = new Mock(); + this.mockMapper = new Mock(); + this.mockBlobService = new Mock(); + this.mockLoggerService = new Mock(); + this.mockArtRepository = new Mock(); + + this.mockRepository + .Setup(r => r.ArtRepository) + .Returns(this.mockArtRepository.Object); + + this.mapper = new MapperConfiguration(cfg => + { + cfg.CreateMap(); + }).CreateMapper(); + + this.handler = new GetArtsByStreetcodeIdHandler( + this.mockRepository.Object, + this.mapper, + this.mockBlobService.Object, + this.mockLoggerService.Object); + } + + /// + /// Method returns correct arts, if entered valid streetcodeId. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task Handle_ValidStreetcodeId_ReturnCorrectArts() + { + var query = new GetArtsByStreetcodeIdQuery(1); + + var expectedCount = 1; + + var arts = new List() + { + new DAL.Entities.Media.Images.Art() + { + Id = 1, + Description = "Description art 1", + ImageId = 1, + Title = "Title art 1", + StreetcodeArts = new List() + { + new StreetcodeArt() + { + ArtId = 1, + StreetcodeId = 1, + }, + }, + }, + }; + + this.mockArtRepository + .Setup(r => r.GetAllAsync( + It.IsAny>>(), + It.IsAny, + IIncludableQueryable>>())) + .ReturnsAsync(arts); + + var result = await this.handler.Handle(query, CancellationToken.None); + + Assert.Equal(expectedCount, result.Value.Count()); + } + + /// + /// Method returns error message, if streetcode not exist arts. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task Handle_ValidStretcodeIdWithEmptyArts_ReturnErrorMessage() + { + var query = new GetArtsByStreetcodeIdQuery(1); + + var expectedErrorMessage = $"Cannot find any art with corresponding streetcode id: {query.StreetcodeId}"; + + this.mockArtRepository + .Setup(r => r.GetAllAsync( + It.IsAny>>(), + It.IsAny, + IIncludableQueryable>>())) + .ReturnsAsync((List?)null); + + var result = await this.handler.Handle(query, CancellationToken.None); + + Assert.Equal(expectedErrorMessage, result.Errors.First().Message); + } + } +} From 6624ef410607b6efd6b2947826c516b9f1b138eb Mon Sep 17 00:00:00 2001 From: BodyaAP <53657043+BodyaAP@users.noreply.github.com> Date: Thu, 14 May 2026 14:20:11 +0300 Subject: [PATCH 3/5] Added more assert --- .gitignore | 3 +- Streetcode/Streetcode.WebApi/Program.cs | 2 +- .../Streetcode.WebApi/appsettings.Local.json | 11 + Streetcode/Streetcode.WebApi/appsettings.json | 55 +++++ .../Art/GetAll/GetAllArtsHandlerTests.cs | 211 ++++++++++-------- .../Art/GetById/GetArtByIdHandlerTests.cs | 83 ++++--- .../GetArtByStreetcodeIdHandlerTests.cs | 93 +++++--- 7 files changed, 309 insertions(+), 149 deletions(-) create mode 100644 Streetcode/Streetcode.WebApi/appsettings.Local.json create mode 100644 Streetcode/Streetcode.WebApi/appsettings.json diff --git a/.gitignore b/.gitignore index fc4c4df..d17a741 100644 --- a/.gitignore +++ b/.gitignore @@ -345,5 +345,4 @@ healthchecksdb # BlobStorage BlobStorageFolder/ BlobStorageTestFolder/ -/Streetcode/Streetcode.WebApi/appsettings.json -/Streetcode/Streetcode.WebApi/appsettings.Local.json + diff --git a/Streetcode/Streetcode.WebApi/Program.cs b/Streetcode/Streetcode.WebApi/Program.cs index d0ce7a8..02523a8 100644 --- a/Streetcode/Streetcode.WebApi/Program.cs +++ b/Streetcode/Streetcode.WebApi/Program.cs @@ -27,7 +27,7 @@ await app.ApplyMigrations(); -await app.SeedDataAsync(); // uncomment for seeding data in local +// await app.SeedDataAsync(); // uncomment for seeding data in local app.UseCors(); app.UseHttpsRedirection(); app.UseRouting(); diff --git a/Streetcode/Streetcode.WebApi/appsettings.Local.json b/Streetcode/Streetcode.WebApi/appsettings.Local.json new file mode 100644 index 0000000..ca9e001 --- /dev/null +++ b/Streetcode/Streetcode.WebApi/appsettings.Local.json @@ -0,0 +1,11 @@ +{ + "ConnectionStrings": { + "DefaultConnection": "Server=localhost\\SQLEXPRESS01;Database=StreetcodeDb;User Id=sa;Password=Admin@1234;MultipleActiveResultSets=true" + }, + "CORS": { + "AllowedOrigins": [ "http://localhost:3000" ], + "AllowedHeaders": [ "*" ], + "AllowedMethods": [ "*" ], + "PreflightMaxAge": 1 + } +} diff --git a/Streetcode/Streetcode.WebApi/appsettings.json b/Streetcode/Streetcode.WebApi/appsettings.json new file mode 100644 index 0000000..b9a6a9a --- /dev/null +++ b/Streetcode/Streetcode.WebApi/appsettings.json @@ -0,0 +1,55 @@ +{ + "ConnectionStrings": { + "DefaultConnection": "Server=localhost\\SQLEXPRESS01;Database=StreetcodeDb;User Id=sa;Password=Admin@1234;MultipleActiveResultSets=true" + }, + "EmailConfiguration": { + "From": "streetcodefeedback@gmail.com", + "To": "streetcodeua@gmail.com", + "SmtpServer": "smtp.gmail.com", + "Port": 465, + "Username": "streetcodefeedback@gmail.com" + }, + "Serilog": { + "Using": [], + "MinimumLevel": { + "Default": "Information", + "Microsoft": "Warning", + "System": "Warning" + }, + "Enrich": [ + "FromLogContext", + "WithMachineName", + "WithProcessId", + "WithThreadId" + ], + "WriteTo": [ + { + "Name": "Console" + } + ] + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "Blob": { + "BlobStoreKey": "SlavaKasterovSuperGoodInshalaKey", + "BlobStorePath": "../../BlobStorageFolder/" + }, + "Payment": { + "Token": "BombasticTokenForMonobank" + }, + "Instagram": { + "InstagramID": "NiceIdForInstagram", + "InstagramToken": "SuperNiceTokenForInstagram" + }, + "CORS": { + "AllowedOrigins": [], + "AllowedHeaders": [], + "AllowedMethods": [], + "PreflightMaxAge": 1 + } +} diff --git a/Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetAll/GetAllArtsHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetAll/GetAllArtsHandlerTests.cs index 21174cf..2ee7038 100644 --- a/Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetAll/GetAllArtsHandlerTests.cs +++ b/Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetAll/GetAllArtsHandlerTests.cs @@ -1,111 +1,144 @@ -using AutoMapper; -using FluentResults; -using Microsoft.EntityFrameworkCore.Query; -using Moq; -using Repositories.Interfaces; -using Streetcode.BLL.DTO.Media.Art; -using Streetcode.BLL.Interfaces.Logging; -using Streetcode.BLL.MediatR.Media.Art.GetAll; -using Streetcode.DAL.Entities.Media.Images; -using Streetcode.DAL.Repositories.Interfaces.Base; -using System.Linq.Expressions; -using Xunit; - -namespace Streetcode.XUnitTest.BLL.MediatR.Media.Art.GetAll; - -/// -/// Tests for GetAllArtsHandler. -/// -public class GetAllArtsHandlerTests +namespace Streetcode.XUnitTest.BLL.MediatR.Media.Art.GetAll { - private GetAllArtsHandler handler; - - private Mock mockMapper; - private Mock mockRepository; - private Mock mockArtRepository; - private Mock mockLoggerService; - - private IMapper mapper; + using System.Linq.Expressions; + using AutoMapper; + using FluentResults; + using Microsoft.EntityFrameworkCore.Query; + using Moq; + using Repositories.Interfaces; + using Streetcode.BLL.DTO.Media.Art; + using Streetcode.BLL.Interfaces.Logging; + using Streetcode.BLL.MediatR.Media.Art.GetAll; + using Streetcode.DAL.Entities.Media.Images; + using Streetcode.DAL.Repositories.Interfaces.Base; + using Xunit; /// - /// Initializes a new instance of the class. + /// Tests for GetAllArtsHandler. /// - public GetAllArtsHandlerTests() + public class GetAllArtsHandlerTests { - this.mockMapper = new Mock(); - this.mockRepository = new Mock(); - this.mockArtRepository = new Mock(); - this.mockLoggerService = new Mock(); + private GetAllArtsHandler handler; + + private Mock mockMapper; + private Mock mockRepository; + private Mock mockArtRepository; + private Mock mockLoggerService; - this.mockRepository - .Setup(r => r.ArtRepository) - .Returns(this.mockArtRepository.Object); + private IMapper mapper; - this.mapper = new MapperConfiguration(cfg => + /// + /// Initializes a new instance of the class. + /// + public GetAllArtsHandlerTests() { - cfg.CreateMap(); - }).CreateMapper(); + this.mockMapper = new Mock(); + this.mockRepository = new Mock(); + this.mockArtRepository = new Mock(); + this.mockLoggerService = new Mock(); - this.handler = new GetAllArtsHandler( - this.mockRepository.Object, - this.mapper, - this.mockLoggerService.Object); - } + this.mockRepository + .Setup(r => r.ArtRepository) + .Returns(this.mockArtRepository.Object); - /// - /// Method Handel returns all Arts, if they are. - /// - /// A representing the asynchronous unit test. - [Fact] - public async Task Handle_ArtsNotEmpty_ReturnAllArts() - { - var query = new GetAllArtsQuery(); + this.mapper = new MapperConfiguration(cfg => + { + cfg.CreateMap(); + }).CreateMapper(); + + this.handler = new GetAllArtsHandler( + this.mockRepository.Object, + this.mapper, + this.mockLoggerService.Object); + } + + /// + /// Method Handel returns all Arts, if they are. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task Handle_ArtsNotEmpty_ReturnAllArts() + { + // Arrange + var query = new GetAllArtsQuery(); - int expectedCount = 1; + int expectedCount = 1; + string expectedTitle = "Title art 1"; - var arts = new List() - { - new DAL.Entities.Media.Images.Art() + var arts = new List() { - Id = 1, - Description = "Description art 1", - ImageId = 1, - Title = "Title art 1", - }, - }; - - this.mockArtRepository - .Setup(r => r.GetAllAsync( - It.IsAny>>(), - It.IsAny, - IIncludableQueryable>>())) - .ReturnsAsync(arts); + new Art() + { + Id = 1, + Description = "Description art 1", + ImageId = 1, + Title = "Title art 1", + }, + }; - var result = await this.handler.Handle(query, CancellationToken.None); + this.mockArtRepository + .Setup(r => r.GetAllAsync( + It.IsAny>>(), + It.IsAny, + IIncludableQueryable>>())) + .ReturnsAsync(arts); - Assert.Equal(expectedCount, result.Value.Count()); - } + // Act + var result = await this.handler.Handle(query, CancellationToken.None); - /// - /// Method Handle return error message, if Arts do not exist. - /// - /// A representing the asynchronous unit test. - [Fact] - public async Task Handle_ArtsIsEmpty_ReturnErrorMessage() - { - var query = new GetAllArtsQuery(); + // Assert + Assert.True(result.IsSuccess); + + Assert.NotNull(result.Value); + + Assert.Equal(expectedCount, result.Value.Count()); + + Assert.Equal(expectedTitle, result.Value.First().Title); + + Assert.All(result.Value, item => + { + Assert.IsType(item); + }); + + this.mockArtRepository.Verify(r => r.GetAllAsync( + It.IsAny>>(), + It.IsAny, + IIncludableQueryable>>()), + Times.Once); + } + + /// + /// Method Handle return error message, if Arts do not exist. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task Handle_ArtsIsEmpty_ReturnErrorMessage() + { + // Arrange + var query = new GetAllArtsQuery(); + + var expectedError = new Error($"Cannot find any arts"); + + this.mockArtRepository + .Setup(r => r.GetAllAsync( + It.IsAny>>(), + It.IsAny, + IIncludableQueryable>>())) + .ReturnsAsync((List?)null); - var expectedError = new Error($"Cannot find any arts"); + // Act + var result = await this.handler.Handle(query, CancellationToken.None); - this.mockArtRepository - .Setup(r => r.GetAllAsync( - It.IsAny>>(), - It.IsAny, - IIncludableQueryable>>())) - .ReturnsAsync((List?)null); + // Assert + Assert.True(result.IsFailed); - var result = await this.handler.Handle(query, CancellationToken.None); + Assert.Equal(expectedError.Message, result.Errors.First().Message); - Assert.Equal(expectedError.Message, result.Errors.First().Message); + this.mockArtRepository.Verify(r => r.GetAllAsync( + It.IsAny>>(), + It.IsAny, + IIncludableQueryable>>()), + Times.Once); + } } } diff --git a/Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetById/GetArtByIdHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetById/GetArtByIdHandlerTests.cs index 1681ff7..3e5bc41 100644 --- a/Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetById/GetArtByIdHandlerTests.cs +++ b/Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetById/GetArtByIdHandlerTests.cs @@ -1,22 +1,23 @@ -using AutoMapper; -using Microsoft.EntityFrameworkCore.Query; -using Moq; -using Org.BouncyCastle.Asn1.Ocsp; -using Repositories.Interfaces; -using Streetcode.BLL.DTO.Media.Art; -using Streetcode.BLL.Interfaces.Logging; -using Streetcode.BLL.MediatR.Media.Art.GetById; -using Streetcode.DAL.Repositories.Interfaces.Base; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Text; -using System.Threading.Tasks; -using Xunit; - -namespace Streetcode.XUnitTest.BLL.MediatR.Media.Art.GetById +namespace Streetcode.XUnitTest.BLL.MediatR.Media.Art.GetById { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Linq.Expressions; + using System.Text; + using System.Threading.Tasks; + using AutoMapper; + using Microsoft.EntityFrameworkCore.Query; + using Moq; + using Org.BouncyCastle.Asn1.Ocsp; + using Repositories.Interfaces; + using Streetcode.BLL.DTO.Media.Art; + using Streetcode.BLL.Interfaces.Logging; + using Streetcode.BLL.MediatR.Media.Art.GetById; + using Streetcode.DAL.Entities.Media.Images; + using Streetcode.DAL.Repositories.Interfaces.Base; + using Xunit; + /// /// Checking class GetArtByIdHandler. /// @@ -56,9 +57,10 @@ public GetArtByIdHandlerTests() [Fact] public async Task Handle_ValidId_ReturnArt() { + // Arrange var query = new GetArtByIdQuery(1); - var art = new DAL.Entities.Media.Images.Art() + var art = new Art() { Id = 1, Description = "Description art 1", @@ -76,19 +78,34 @@ public async Task Handle_ValidId_ReturnArt() this.mockArtRepository .Setup(r => r.GetFirstOrDefaultAsync( - It.IsAny>>(), - It.IsAny, - IIncludableQueryable>>())) + It.IsAny>>(), + It.IsAny, + IIncludableQueryable>>())) .ReturnsAsync(art); this.mockMapper .Setup(m => m.Map( - It.IsAny())) + It.IsAny())) .Returns(artDTO); + // Act var result = await this.handler.Handle(query, CancellationToken.None); + // Assert + Assert.True(result.IsSuccess); + + Assert.NotNull(result.Value); + Assert.Equal(artDTO.Id, result.Value.Id); + + Assert.Equal(artDTO.Title, result.Value.Title); + + this.mockArtRepository + .Verify(r => r.GetFirstOrDefaultAsync( + It.IsAny>>(), + It.IsAny, + IIncludableQueryable>>()), + Times.Once); } /// @@ -98,20 +115,32 @@ public async Task Handle_ValidId_ReturnArt() [Fact] public async Task Handle_NotValidId_ReturnError() { + // Arrange var query = new GetArtByIdQuery(2); string expectedErrorMsg = $"Cannot find an art with corresponding id: {query.Id}"; this.mockArtRepository .Setup(r => r.GetFirstOrDefaultAsync( - It.IsAny>>(), - It.IsAny, - IIncludableQueryable>>())) - .ReturnsAsync((DAL.Entities.Media.Images.Art?)null); + It.IsAny>>(), + It.IsAny, + IIncludableQueryable>>())) + .ReturnsAsync((Art?)null); + // Act var result = await this.handler.Handle(query, CancellationToken.None); + // Assert + Assert.True(result.IsFailed); + Assert.Equal(expectedErrorMsg, result.Errors.First().Message); + + this.mockArtRepository + .Verify(r => r.GetFirstOrDefaultAsync( + It.IsAny>>(), + It.IsAny, + IIncludableQueryable>>()), + Times.Once); } } } diff --git a/Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetByStreetcodeId/GetArtByStreetcodeIdHandlerTests.cs b/Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetByStreetcodeId/GetArtByStreetcodeIdHandlerTests.cs index 4605e58..d9f2ff5 100644 --- a/Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetByStreetcodeId/GetArtByStreetcodeIdHandlerTests.cs +++ b/Streetcode/Streetcode.XUnitTest/BLL/MediatR/Media/Art/GetByStreetcodeId/GetArtByStreetcodeIdHandlerTests.cs @@ -1,26 +1,26 @@ -using AutoMapper; -using Castle.Core.Logging; -using Microsoft.EntityFrameworkCore.Query; -using Moq; -using Org.BouncyCastle.Asn1.Ocsp; -using Repositories.Interfaces; -using Streetcode.BLL.DTO.Media.Art; -using Streetcode.BLL.Interfaces.BlobStorage; -using Streetcode.BLL.Interfaces.Logging; -using Streetcode.BLL.MediatR.Media.Art.GetByStreetcodeId; -using Streetcode.DAL.Entities.Media.Images; -using Streetcode.DAL.Entities.Streetcode; -using Streetcode.DAL.Repositories.Interfaces.Base; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Text; -using System.Threading.Tasks; -using Xunit; - -namespace Streetcode.XUnitTest.BLL.MediatR.Media.Art.GetByStreetcodeId +namespace Streetcode.XUnitTest.BLL.MediatR.Media.Art.GetByStreetcodeId { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Linq.Expressions; + using System.Text; + using System.Threading.Tasks; + using AutoMapper; + using Castle.Core.Logging; + using Microsoft.EntityFrameworkCore.Query; + using Moq; + using Org.BouncyCastle.Asn1.Ocsp; + using Repositories.Interfaces; + using Streetcode.BLL.DTO.Media.Art; + using Streetcode.BLL.Interfaces.BlobStorage; + using Streetcode.BLL.Interfaces.Logging; + using Streetcode.BLL.MediatR.Media.Art.GetByStreetcodeId; + using Streetcode.DAL.Entities.Media.Images; + using Streetcode.DAL.Entities.Streetcode; + using Streetcode.DAL.Repositories.Interfaces.Base; + using Xunit; + /// /// Checking class GetArtByStreetcodeIdHandler. /// @@ -70,11 +70,14 @@ public GetArtByStreetcodeIdHandlerTests() [Fact] public async Task Handle_ValidStreetcodeId_ReturnCorrectArts() { + // Arrange var query = new GetArtsByStreetcodeIdQuery(1); var expectedCount = 1; - var arts = new List() + string expectedTitle = "Title art 1"; + + var arts = new List() { new DAL.Entities.Media.Images.Art() { @@ -95,14 +98,33 @@ public async Task Handle_ValidStreetcodeId_ReturnCorrectArts() this.mockArtRepository .Setup(r => r.GetAllAsync( - It.IsAny>>(), - It.IsAny, - IIncludableQueryable>>())) + It.IsAny>>(), + It.IsAny, + IIncludableQueryable>>())) .ReturnsAsync(arts); + // Act var result = await this.handler.Handle(query, CancellationToken.None); + // Assert + Assert.True(result.IsSuccess); + + Assert.NotNull(result.Value); + Assert.Equal(expectedCount, result.Value.Count()); + + Assert.Equal(expectedTitle, result.Value.First().Title); + + Assert.All(result.Value, item => + { + Assert.IsType(item); + }); + + this.mockArtRepository.Verify(r => r.GetAllAsync( + It.IsAny>>(), + It.IsAny, + IIncludableQueryable>>()), + Times.Once); } /// @@ -112,20 +134,31 @@ public async Task Handle_ValidStreetcodeId_ReturnCorrectArts() [Fact] public async Task Handle_ValidStretcodeIdWithEmptyArts_ReturnErrorMessage() { + // Arrange var query = new GetArtsByStreetcodeIdQuery(1); var expectedErrorMessage = $"Cannot find any art with corresponding streetcode id: {query.StreetcodeId}"; this.mockArtRepository .Setup(r => r.GetAllAsync( - It.IsAny>>(), - It.IsAny, - IIncludableQueryable>>())) - .ReturnsAsync((List?)null); + It.IsAny>>(), + It.IsAny, + IIncludableQueryable>>())) + .ReturnsAsync((List?)null); + // Act var result = await this.handler.Handle(query, CancellationToken.None); + // Assert + Assert.True(result.IsFailed); + Assert.Equal(expectedErrorMessage, result.Errors.First().Message); + + this.mockArtRepository.Verify(r => r.GetAllAsync( + It.IsAny>>(), + It.IsAny, + IIncludableQueryable>>()), + Times.Once); } } } From 75cfe52787d35d2f2a3a169400b96127b8b3d2e7 Mon Sep 17 00:00:00 2001 From: BodyaAP <53657043+BodyaAP@users.noreply.github.com> Date: Thu, 14 May 2026 16:42:51 +0300 Subject: [PATCH 4/5] Update appsettings.json --- Streetcode/Streetcode.WebApi/appsettings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Streetcode/Streetcode.WebApi/appsettings.json b/Streetcode/Streetcode.WebApi/appsettings.json index b9a6a9a..7e1e684 100644 --- a/Streetcode/Streetcode.WebApi/appsettings.json +++ b/Streetcode/Streetcode.WebApi/appsettings.json @@ -1,6 +1,6 @@ { "ConnectionStrings": { - "DefaultConnection": "Server=localhost\\SQLEXPRESS01;Database=StreetcodeDb;User Id=sa;Password=Admin@1234;MultipleActiveResultSets=true" + "DefaultConnection": "Server=127.0.0.1;Database=StreetcodeDb;User Id=sa;Password=Admin@1234;MultipleActiveResultSets=true" }, "EmailConfiguration": { "From": "streetcodefeedback@gmail.com", From c2af6b2cfc1dc5ad46d981c658d07201f507c9a5 Mon Sep 17 00:00:00 2001 From: BodyaAP <53657043+BodyaAP@users.noreply.github.com> Date: Thu, 14 May 2026 17:53:53 +0300 Subject: [PATCH 5/5] Update DefaultConnection in appsettings.json Removed User Id and Password from DefaultConnection. --- Streetcode/Streetcode.WebApi/appsettings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Streetcode/Streetcode.WebApi/appsettings.json b/Streetcode/Streetcode.WebApi/appsettings.json index 7e1e684..01009a6 100644 --- a/Streetcode/Streetcode.WebApi/appsettings.json +++ b/Streetcode/Streetcode.WebApi/appsettings.json @@ -1,6 +1,6 @@ { "ConnectionStrings": { - "DefaultConnection": "Server=127.0.0.1;Database=StreetcodeDb;User Id=sa;Password=Admin@1234;MultipleActiveResultSets=true" + "DefaultConnection": "Server=127.0.0.1;Database=StreetcodeDb;MultipleActiveResultSets=true" }, "EmailConfiguration": { "From": "streetcodefeedback@gmail.com",