Skip to content

Commit

Permalink
Added Tests to the AsyncProcessing package
Browse files Browse the repository at this point in the history
(#release-note: Added Tests to the AsyncProcessing package#)
  • Loading branch information
Farshad DASHTI authored and Farshad DASHTI committed Oct 9, 2024
1 parent 10e017a commit 193cff6
Show file tree
Hide file tree
Showing 11 changed files with 166 additions and 8 deletions.
1 change: 0 additions & 1 deletion .github/workflows/build-test-asyncprocessing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,5 @@ jobs:
with:
project_name: DfE.CoreLibs.AsyncProcessing
project_path: src/DfE.CoreLibs.AsyncProcessing
run_tests: false
secrets:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
1 change: 0 additions & 1 deletion .github/workflows/build-test-template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ env:
DOTNET_VERSION: '8.0.x'
EF_VERSION: '6.0.5'
JAVA_VERSION: '17'
CONNECTION_STRING: 'Server=localhost,1433;Database=sip;TrustServerCertificate=True;User Id=sa;Password=StrongPassword905'

jobs:
build-and-test:
Expand Down
7 changes: 7 additions & 0 deletions DfE.CoreLibs.sln
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DfE.CoreLibs.Http.Tests", "
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DfE.CoreLibs.Caching.Tests", "src\Tests\DfE.CoreLibs.Caching.Tests\DfE.CoreLibs.Caching.Tests.csproj", "{807147EB-9B76-42F6-B249-A0F0CF3C3462}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DfE.CoreLibs.AsyncProcessing.Tests", "src\Tests\DfE.CoreLibs.AsyncProcessing.Tests\DfE.CoreLibs.AsyncProcessing.Tests.csproj", "{5ABF8802-0C35-42D3-B2BB-83BD7159124F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -65,6 +67,10 @@ Global
{807147EB-9B76-42F6-B249-A0F0CF3C3462}.Debug|Any CPU.Build.0 = Debug|Any CPU
{807147EB-9B76-42F6-B249-A0F0CF3C3462}.Release|Any CPU.ActiveCfg = Release|Any CPU
{807147EB-9B76-42F6-B249-A0F0CF3C3462}.Release|Any CPU.Build.0 = Release|Any CPU
{5ABF8802-0C35-42D3-B2BB-83BD7159124F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5ABF8802-0C35-42D3-B2BB-83BD7159124F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5ABF8802-0C35-42D3-B2BB-83BD7159124F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5ABF8802-0C35-42D3-B2BB-83BD7159124F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -73,6 +79,7 @@ Global
{07AE8F19-9566-4F0C-92E6-0A2BF122DCC9} = {3F89DCAD-8EC7-41ED-A08F-A9EFAE263EB4}
{69529D73-DD34-43A2-9D06-F3783F68F05C} = {3F89DCAD-8EC7-41ED-A08F-A9EFAE263EB4}
{807147EB-9B76-42F6-B249-A0F0CF3C3462} = {3F89DCAD-8EC7-41ED-A08F-A9EFAE263EB4}
{5ABF8802-0C35-42D3-B2BB-83BD7159124F} = {3F89DCAD-8EC7-41ED-A08F-A9EFAE263EB4}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {01D11FBC-6C66-43E4-8F1F-46B105EDD95C}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
<ItemGroup>
<PackageReference Include="MediatR" Version="12.4.1" />
<PackageReference Include="MediatR.Contracts" Version="2.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.1" />
<PackageReference Include="System.Text.Json" Version="8.0.5" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
using System.Diagnostics.CodeAnalysis;

namespace DfE.CoreLibs.Contracts.Academies.V1.EducationalPerformance
{
/// <summary>
/// Absence Data Response
/// </summary>
[ExcludeFromCodeCoverage]
public class SchoolAbsenceDataDto
{
/// <summary>
Expand Down
5 changes: 4 additions & 1 deletion src/DfE.CoreLibs.Contracts/Academies/V4/AddressDto.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
namespace DfE.CoreLibs.Contracts.Academies.V4;
using System.Diagnostics.CodeAnalysis;

namespace DfE.CoreLibs.Contracts.Academies.V4;

[Serializable]
[ExcludeFromCodeCoverage]
public class AddressDto
{
public string Street { get; set; }

Check warning on line 9 in src/DfE.CoreLibs.Contracts/Academies/V4/AddressDto.cs

View workflow job for this annotation

GitHub Actions / build-and-test / build-and-test

Non-nullable property 'Street' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 9 in src/DfE.CoreLibs.Contracts/Academies/V4/AddressDto.cs

View workflow job for this annotation

GitHub Actions / build-and-package / build-and-package

Non-nullable property 'Street' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
namespace DfE.CoreLibs.Contracts.Academies.V4.Establishments;
using System.Diagnostics.CodeAnalysis;

namespace DfE.CoreLibs.Contracts.Academies.V4.Establishments;

[Serializable]
[ExcludeFromCodeCoverage]
public class EstablishmentDto
{

Expand Down
6 changes: 5 additions & 1 deletion src/DfE.CoreLibs.Contracts/Academies/V4/PagedDataResponse.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
namespace DfE.CoreLibs.Contracts.Academies.V4;
using System.Diagnostics.CodeAnalysis;

namespace DfE.CoreLibs.Contracts.Academies.V4;

[Serializable]
[ExcludeFromCodeCoverage]
public class PagedDataResponse<TResponse> where TResponse : class
{

Expand All @@ -20,6 +23,7 @@ public PagedDataResponse(IEnumerable<TResponse> data, PagingResponse pagingRespo
}

[Serializable]
[ExcludeFromCodeCoverage]
public class PagingResponse
{
public int Page { get; set; }
Expand Down
2 changes: 2 additions & 0 deletions src/DfE.CoreLibs.Contracts/Academies/V4/Trusts/TrustDto.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using DfE.CoreLibs.Contracts.Academies.V4.Establishments;
using System.Diagnostics.CodeAnalysis;

namespace DfE.CoreLibs.Contracts.Academies.V4.Trusts;

[Serializable]
[ExcludeFromCodeCoverage]
public class TrustDto
{
public string Name { get; set; }

Check warning on line 10 in src/DfE.CoreLibs.Contracts/Academies/V4/Trusts/TrustDto.cs

View workflow job for this annotation

GitHub Actions / build-and-test / build-and-test

Non-nullable property 'Name' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="MediatR" Version="12.4.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="xunit" Version="2.5.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\DfE.CoreLibs.AsyncProcessing\DfE.CoreLibs.AsyncProcessing.csproj" />
<ProjectReference Include="..\..\DfE.CoreLibs.Testing\DfE.CoreLibs.Testing.csproj" />
</ItemGroup>

<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
using DfE.CoreLibs.AsyncProcessing.Interfaces;
using DfE.CoreLibs.AsyncProcessing.Services;
using DfE.CoreLibs.Testing.AutoFixture.Attributes;
using MediatR;
using NSubstitute;

namespace DfE.CoreLibs.AsyncProcessing.Tests.Services
{
public class BackgroundServiceFactoryTests
{
private readonly IMediator _mediator;
private readonly BackgroundServiceFactory _backgroundServiceFactory;

public BackgroundServiceFactoryTests()
{
_mediator = Substitute.For<IMediator>();
_backgroundServiceFactory = new BackgroundServiceFactory(_mediator);
}

[Theory]
[CustomAutoData]
public async Task EnqueueTask_ShouldProcessTaskInQueue(
Func<Task<int>> taskFunc,
IBackgroundServiceEvent eventMock)
{
// Arrange
Func<int, IBackgroundServiceEvent> eventFactory = _ => eventMock;

var semaphore = new SemaphoreSlim(0, 1);
bool taskExecuted = false;

Func<Task<int>> wrappedTaskFunc = async () =>
{
taskExecuted = true;
semaphore.Release();
return await taskFunc();
};

// Act
_backgroundServiceFactory.EnqueueTask(wrappedTaskFunc, eventFactory);

// Ensure the task gets processed
await semaphore.WaitAsync(1000);

// Assert
Assert.True(taskExecuted, "Task in the queue should have been processed.");
}

[Theory]
[CustomAutoData]
public async Task EnqueueTask_ShouldPublishEvent_WhenEventFactoryIsProvided(
int taskResult,
IBackgroundServiceEvent eventMock)
{
// Arrange
Func<int, IBackgroundServiceEvent> eventFactory = _ => eventMock;

// Act
_backgroundServiceFactory.EnqueueTask(() => Task.FromResult(taskResult), eventFactory);

// Trigger processing
await Task.Delay(100);

// Assert
await _mediator.Received(1).Publish(eventMock, Arg.Any<CancellationToken>());
}

[Theory]
[CustomAutoData]
public async Task StartProcessingQueue_ShouldProcessTasksSequentially(
Func<Task<int>> taskFunc,
IBackgroundServiceEvent eventMock)
{
// Arrange
Func<int, IBackgroundServiceEvent> eventFactory = _ => eventMock;

int taskCount = 0;
Func<Task<int>> wrappedTaskFunc = async () =>
{
Interlocked.Increment(ref taskCount);
return await taskFunc();
};

_backgroundServiceFactory.EnqueueTask(wrappedTaskFunc, eventFactory);
_backgroundServiceFactory.EnqueueTask(wrappedTaskFunc, eventFactory);

// Act
await Task.Delay(100); // Allow time for processing

// Assert
Assert.Equal(2, taskCount);
}

[Fact]
public async Task ExecuteAsync_ShouldStopProcessing_WhenCancellationRequested()
{
// Arrange
using var cts = new CancellationTokenSource();
var task = _backgroundServiceFactory.StartAsync(cts.Token);

// Act
await cts.CancelAsync();
await task;

// Assert
Assert.True(task.IsCompletedSuccessfully);
}
}
}

0 comments on commit 193cff6

Please sign in to comment.