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",