Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
7a22263
Add test Handle_ReturnsNullResult_WhenTextNotFoundButStreetcodeExists
NikitaPankin May 12, 2026
094dccd
Add test Handle_ReturnsError_WhenStreetcodeDoesNotExist
NikitaPankin May 12, 2026
f2da0cc
Add test Handle_UsesAddTermsTagResult_AsTextContent
NikitaPankin May 12, 2026
88b6c96
Add test AddTermsTag_ReturnsNull_WhenInputIsNull
NikitaPankin May 12, 2026
574d79d
Add test AddTermsTag_WrapsWord_WhenDirectTermMatchFound
NikitaPankin May 12, 2026
3af1ce7
Add test AddTermsTag_WrapsFirstOccurrence_AndSkipsSubsequent
NikitaPankin May 12, 2026
e682907
Add test AddTermsTag_SkipsHTMLTags_WhenSplittingWords
NikitaPankin May 12, 2026
5402dd3
Add test Handle_ReturnsError_WhenServiceReturnsNull
NikitaPankin May 12, 2026
66f2fcc
Replased AddTermsTag_ReturnsNull_WhenInputIsNull with AddTermsTag_Thr…
NikitaPankin May 12, 2026
660ba28
Add test Handle_ReturnsProcessedText_WhenTextExists
NikitaPankin May 13, 2026
34c46e5
Add tests Handle_ReturnsProcessedText_WhenServiceSucceeds and Handle_…
NikitaPankin May 13, 2026
d0729b3
Add GetTextByIdHandler tests
NikitaPankin May 13, 2026
b5c67e2
Add GetAllTextsHandler tests
NikitaPankin May 13, 2026
daf0189
Merge branch 'dev' into test/6/streetcode-text
NikitaPankin May 13, 2026
d9910bf
Merge branch 'dev' into test/6/streetcode-text
NikitaPankin May 13, 2026
b4a6817
Replaced mapper mock with mapper, add descriptions
NikitaPankin May 15, 2026
0ef0628
renamed Streetcode to StreetCode in Streetcode.XUnitTest.BLL.MediatR …
NikitaPankin May 15, 2026
139905f
Merge branch 'dev' into test/6/streetcode-text
PenultimateBoss May 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// <copyright file="GetAllTextsHandlerTests.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>

namespace Streetcode.XUnitTest.BLL.MediatR.StreetCode.Text
{
using System.Linq.Expressions;
using AutoMapper;
using FluentAssertions;
using Microsoft.EntityFrameworkCore.Query;
using Moq;
using Streetcode.BLL.DTO.Streetcode.TextContent.Text;
using Streetcode.BLL.Interfaces.Logging;
using Streetcode.BLL.Mapping.Streetcode.TextContent;
using Streetcode.BLL.MediatR.Streetcode.Text.GetAll;
using Streetcode.DAL.Repositories.Interfaces.Base;
using Streetcode.DAL.Repositories.Interfaces.Streetcode.TextContent;
using Xunit;
using TextEntity = Streetcode.DAL.Entities.Streetcode.TextContent.Text;

/// <summary>
/// Unit tests for <see cref="GetAllTextsHandler"/>.
/// </summary>
public class GetAllTextsHandlerTests
{
private readonly Mock<IRepositoryWrapper> repositoryWrapperMock;
private readonly Mock<ITextRepository> textRepositoryMock;
private readonly IMapper mapper;
private readonly Mock<ILoggerService> loggerMock;
private readonly GetAllTextsHandler handler;

/// <summary>
/// Initializes a new instance of the <see cref="GetAllTextsHandlerTests"/> class.
/// </summary>
public GetAllTextsHandlerTests()
{
this.repositoryWrapperMock = new Mock<IRepositoryWrapper>();
this.textRepositoryMock = new Mock<ITextRepository>();
this.mapper = new MapperConfiguration(cfg => cfg.AddProfile<TextProfile>()).CreateMapper();
this.loggerMock = new Mock<ILoggerService>();

this.repositoryWrapperMock
.Setup(w => w.TextRepository)
.Returns(this.textRepositoryMock.Object);

this.handler = new GetAllTextsHandler(
this.repositoryWrapperMock.Object,
this.mapper,
this.loggerMock.Object);
}

/// <summary>
/// Tests that the Handle method returns all texts when they exist in the repository.
/// </summary>
/// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
[Fact]
public async Task Handle_ReturnsAllTexts_WhenTextsExist()
{
// Arrange
var query = new GetAllTextsQuery();

var texts = new List<TextEntity>
{
new TextEntity { Id = 1, Title = "Title 1", TextContent = "Content 1", StreetcodeId = 1 },
new TextEntity { Id = 2, Title = "Title 2", TextContent = "Content 2", StreetcodeId = 2 },
};

var textDtos = new List<TextDTO>
{
new TextDTO { Id = 1, Title = "Title 1", TextContent = "Content 1", StreetcodeId = 1 },
new TextDTO { Id = 2, Title = "Title 2", TextContent = "Content 2", StreetcodeId = 2 },
};

this.textRepositoryMock
.Setup(repo => repo.GetAllAsync(
It.IsAny<Expression<Func<TextEntity, bool>>>(),
It.IsAny<Func<IQueryable<TextEntity>, IIncludableQueryable<TextEntity, object>>?>()))
.ReturnsAsync(texts);

// Act
var result = await this.handler.Handle(query, CancellationToken.None);

// Assert
result.IsSuccess.Should().BeTrue();
result.Value.Should().BeEquivalentTo(textDtos);

this.loggerMock.Verify(
l => l.LogError(It.IsAny<object>(), It.IsAny<string>()),
Times.Never);
}

/// <summary>
/// Tests that the Handle method returns an error when the repository returns null.
/// </summary>
/// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
[Fact]
public async Task Handle_ReturnsError_WhenRepositoryReturnsNull()
{
// Arrange
var query = new GetAllTextsQuery();

this.textRepositoryMock
.Setup(repo => repo.GetAllAsync(
It.IsAny<Expression<Func<TextEntity, bool>>>(),
It.IsAny<Func<IQueryable<TextEntity>, IIncludableQueryable<TextEntity, object>>?>()))
.ReturnsAsync((IEnumerable<TextEntity>)null!);

// Act
var result = await this.handler.Handle(query, CancellationToken.None);

// Assert
result.IsFailed.Should().BeTrue();
result.Errors[0].Message.Should().Be("Cannot find any text");

this.loggerMock.Verify(
l => l.LogError(query, "Cannot find any text"),
Times.Once);
}

/// <summary>
/// Tests that the Handle method calls the mapper with the correct entity when texts are retrieved from the repository.
/// </summary>
/// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
[Fact]
public async Task Handle_CallsMapper_WithCorrectEntity()
{
// Arrange
var query = new GetAllTextsQuery();

var texts = new List<TextEntity>
{
new TextEntity { Id = 1, Title = "Title 1", TextContent = "Content 1", StreetcodeId = 1 },
};

this.textRepositoryMock
.Setup(repo => repo.GetAllAsync(
It.IsAny<Expression<Func<TextEntity, bool>>>(),
It.IsAny<Func<IQueryable<TextEntity>, IIncludableQueryable<TextEntity, object>>?>()))
.ReturnsAsync(texts);

// Act
var result = await this.handler.Handle(query, CancellationToken.None);

// Assert
result.IsSuccess.Should().BeTrue();
result.Value.Should().ContainSingle(dto => dto.Id == 1 && dto.Title == "Title 1");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// <copyright file="GetParsedTextAdminPreviewHandlerTests.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>

namespace Streetcode.XUnitTest.BLL.MediatR.StreetCode.Text
{
using FluentAssertions;
using Moq;
using Streetcode.BLL.Interfaces.Text;
using Streetcode.BLL.MediatR.Streetcode.Text.GetParsed;
using Xunit;

/// <summary>
/// Unit tests for <see cref="GetParsedTextAdminPreviewHandler"/>.
/// </summary>
public class GetParsedTextAdminPreviewHandlerTests
{
private readonly Mock<ITextService> textServiceMock;
private readonly GetParsedTextAdminPreviewHandler handler;

/// <summary>
/// Initializes a new instance of the <see cref="GetParsedTextAdminPreviewHandlerTests"/> class.
/// </summary>
public GetParsedTextAdminPreviewHandlerTests()
{
this.textServiceMock = new Mock<ITextService>();
this.handler = new GetParsedTextAdminPreviewHandler(this.textServiceMock.Object);
}

/// <summary>
/// Tests that the Handle method returns an error when the text service returns null, indicating that parsing was unsuccessful.
/// </summary>
/// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
[Fact]
public async Task Handle_ReturnsError_WhenServiceReturnsNull()
{
// Arrange
var command = new GetParsedTextForAdminPreviewCommand(textToParse: "some text");

this.textServiceMock
.Setup(s => s.AddTermsTag(command.textToParse))

Check warning on line 41 in Streetcode/Streetcode.XUnitTest/BLL/MediatR/StreetCode/Text/GetParsedTextAdminPreviewHandlerTests.cs

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Argument of type 'ISetup<ITextService, Task<string>>' cannot be used for parameter 'mock' of type 'IReturns<ITextService, Task<string?>>' in 'IReturnsResult<ITextService> ReturnsExtensions.ReturnsAsync<ITextService, string?>(IReturns<ITextService, Task<string?>> mock, string? value)' due to differences in the nullability of reference types.

See more on https://sonarcloud.io/project/issues?id=ita-social-projects_StreetCode&issues=AZ4rW___7-X1-dWOWNzI&open=AZ4rW___7-X1-dWOWNzI&pullRequest=51
.ReturnsAsync((string?)null);

// Act
var result = await this.handler.Handle(command, CancellationToken.None);

// Assert
result.IsFailed.Should().BeTrue();
result.Errors.Should().ContainSingle(e => e.Message == "text was not parsed successfully");
}

/// <summary>
/// Tests that the Handle method returns the processed text when the text service successfully parses the input text.
/// </summary>
/// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
[Fact]
public async Task Handle_ReturnsProcessedText_WhenServiceSucceeds()
{
// Arrange
const string parsedText = "<Popover><Term>Майдан</Term><Desc>Центральна площа</Desc></Popover>";
var command = new GetParsedTextForAdminPreviewCommand(textToParse: "some text");

this.textServiceMock
.Setup(s => s.AddTermsTag(command.textToParse))
.ReturnsAsync(parsedText);

// Act
var result = await this.handler.Handle(command, CancellationToken.None);

// Assert
result.IsSuccess.Should().BeTrue();
result.Value.Should().Be(parsedText);
}

/// <summary>
/// Tests that the Handle method calls the text service with the original input text, ensuring that the correct data is passed for processing.
/// </summary>
/// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
[Fact]
public async Task Handle_PassesOriginalText_ToService()
{
// Arrange
const string originalText = "raw input text";
var command = new GetParsedTextForAdminPreviewCommand(textToParse: originalText);

this.textServiceMock
.Setup(s => s.AddTermsTag(originalText))
.ReturnsAsync("processed");

// Act
await this.handler.Handle(command, CancellationToken.None);

// Assert
this.textServiceMock.Verify(
s => s.AddTermsTag(originalText),
Times.Once);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// <copyright file="GetTextByIdHandlerTests.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>

namespace Streetcode.XUnitTest.BLL.MediatR.StreetCode.Text
{
using System.Linq.Expressions;
using AutoMapper;
using FluentAssertions;
using Microsoft.EntityFrameworkCore.Query;
using Moq;
using Streetcode.BLL.DTO.Streetcode.TextContent.Text;
using Streetcode.BLL.Interfaces.Logging;
using Streetcode.BLL.Mapping.Streetcode.TextContent;
using Streetcode.BLL.MediatR.Streetcode.Text.GetById;
using Streetcode.DAL.Repositories.Interfaces.Base;
using Streetcode.DAL.Repositories.Interfaces.Streetcode.TextContent;
using Xunit;
using TextEntity = Streetcode.DAL.Entities.Streetcode.TextContent.Text;

/// <summary>
/// Unit tests for <see cref="GetTextByIdHandler"/>.
/// </summary>
public class GetTextByIdHandlerTests
{
private readonly Mock<IRepositoryWrapper> repositoryWrapperMock;
private readonly Mock<ITextRepository> textRepositoryMock;
private readonly IMapper mapper;
private readonly Mock<ILoggerService> loggerMock;
private readonly GetTextByIdHandler handler;

/// <summary>
/// Initializes a new instance of the <see cref="GetTextByIdHandlerTests"/> class.
/// </summary>
public GetTextByIdHandlerTests()
{
this.repositoryWrapperMock = new Mock<IRepositoryWrapper>();
this.textRepositoryMock = new Mock<ITextRepository>();
this.mapper = new MapperConfiguration(cfg => cfg.AddProfile<TextProfile>()).CreateMapper();
this.loggerMock = new Mock<ILoggerService>();

this.repositoryWrapperMock
.Setup(w => w.TextRepository)
.Returns(this.textRepositoryMock.Object);

this.handler = new GetTextByIdHandler(
this.repositoryWrapperMock.Object,
this.mapper,
this.loggerMock.Object);
}

/// <summary>
/// Tests that the Handle method returns a TextDTO when a text with the specified ID exists in the repository.
/// </summary>
/// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
[Fact]
public async Task Handle_ReturnsTextDTO_WhenTextExists()
{
// Arrange
const int textId = 1;
var query = new GetTextByIdQuery(Id: textId);

var textEntity = new TextEntity
{
Id = textId,
Title = "Test Title",
TextContent = "Test Content",
StreetcodeId = 1,
};

var textDto = new TextDTO
{
Id = textId,
Title = "Test Title",
TextContent = "Test Content",
StreetcodeId = 1,
};

this.textRepositoryMock
.Setup(repo => repo.GetFirstOrDefaultAsync(
It.IsAny<Expression<Func<TextEntity, bool>>>(),
It.IsAny<Func<IQueryable<TextEntity>, IIncludableQueryable<TextEntity, object>>?>()))
.ReturnsAsync(textEntity);

// Act
var result = await this.handler.Handle(query, CancellationToken.None);

// Assert
result.IsSuccess.Should().BeTrue();
result.Value.Should().BeEquivalentTo(textDto);

this.loggerMock.Verify(
l => l.LogError(It.IsAny<object>(), It.IsAny<string>()),
Times.Never);
}

/// <summary>
/// Tests that the Handle method returns an error when no text with the specified ID exists in the repository.
/// </summary>
/// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
[Fact]
public async Task Handle_ReturnsError_WhenTextNotFound()
{
// Arrange
const int textId = 42;
var query = new GetTextByIdQuery(Id: textId);

this.textRepositoryMock
.Setup(repo => repo.GetFirstOrDefaultAsync(
It.IsAny<Expression<Func<TextEntity, bool>>>(),
It.IsAny<Func<IQueryable<TextEntity>, IIncludableQueryable<TextEntity, object>>?>()))
.ReturnsAsync((TextEntity?)null);

// Act
var result = await this.handler.Handle(query, CancellationToken.None);

// Assert
result.IsFailed.Should().BeTrue();
result.Errors[0].Message.Should().Be($"Cannot find any text with corresponding id: {textId}");

this.loggerMock.Verify(
l => l.LogError(query, $"Cannot find any text with corresponding id: {textId}"),
Times.Once);
}
}
}
Loading
Loading