Skip to content

Commit

Permalink
Merge pull request #28 from MrDave1999/sample/add-tests
Browse files Browse the repository at this point in the history
 test: Add integration test project for samples
  • Loading branch information
MrDave1999 authored Dec 21, 2023
2 parents e180602 + eeb0e0c commit a7ca1ce
Show file tree
Hide file tree
Showing 16 changed files with 265 additions and 7 deletions.
8 changes: 7 additions & 1 deletion .github/workflows/dotnetcore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,10 @@ jobs:
with:
dotnet-version: ${{ matrix.dotnet-version }}
- name: Test
run: dotnet test ./tests/CPlugin.Net/CPlugin.Net.Tests.csproj
run: |
dotnet test ./tests/CPlugin.Net/CPlugin.Net.Tests.csproj
dotnet build ./samples/Plugins/AppointmentPlugin/Example.AppointmentPlugin.csproj
dotnet build ./samples/Plugins/PersonPlugin/Example.PersonPlugin.csproj
dotnet build ./samples/Plugins/JsonPlugin/Example.JsonPlugin.csproj
dotnet build ./samples/Plugins/OldJsonPlugin/Example.OldJsonPlugin.csproj
dotnet test ./samples/Test/Example.Test.csproj
6 changes: 6 additions & 0 deletions CPlugin.Net.sln
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Example.AppointmentPlugin",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Example.PersonPlugin", "samples\Plugins\PersonPlugin\Example.PersonPlugin.csproj", "{18534944-583B-4924-AC5B-E0655FD92AAC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Example.Test", "samples\Test\Example.Test.csproj", "{1E64908D-DC48-4B83-BB25-CF36821EB37F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestProject.JsonPlugin", "tests\Plugins\TestProject.JsonPlugin\TestProject.JsonPlugin.csproj", "{0F27C776-F284-4C94-86C9-0FF089245E13}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestProject.OldJsonPlugin", "tests\Plugins\TestProject.OldJsonPlugin\TestProject.OldJsonPlugin.csproj", "{BCE8FA91-AF31-49DD-BED8-E60A46915400}"
Expand Down Expand Up @@ -120,6 +122,10 @@ Global
{0BCD3305-F0D5-43E6-B879-EEF0827558A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0BCD3305-F0D5-43E6-B879-EEF0827558A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0BCD3305-F0D5-43E6-B879-EEF0827558A8}.Release|Any CPU.Build.0 = Release|Any CPU
{1E64908D-DC48-4B83-BB25-CF36821EB37F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1E64908D-DC48-4B83-BB25-CF36821EB37F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E64908D-DC48-4B83-BB25-CF36821EB37F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1E64908D-DC48-4B83-BB25-CF36821EB37F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
1 change: 1 addition & 0 deletions samples/Contracts/ICommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ public interface ICommand
{
string Name { get; }
string Description { get; }
string Version { get; }
int Execute();
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ public class PeopleController
public Result<List<Person>> GetAll() => Result.Success(_persons);

[HttpPost]
public Result Create() => Result.Success();
public ActionResult<Result> Create() => Result.CreatedResource().ToActionResult();
}
2 changes: 2 additions & 0 deletions samples/HostApplications/WebApi/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,5 @@
app.MapControllers();

app.Run();

public partial class Program { }
6 changes: 3 additions & 3 deletions samples/Plugins/AppointmentPlugin/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,21 @@ public void ConfigureServices(IServiceCollection services)
{
new()
{
Id = Guid.NewGuid().ToString(),
Id = "16e299b4-a6dc-4aa3-a52c-7dae088241e6",
DoctorName = "Bob",
PatientName = "Alice",
Date = new DateOnly(2023, 01, 01)
},
new()
{
Id = Guid.NewGuid().ToString(),
Id = "5dace456-13d9-42c5-92ea-89869ac44b5c",
DoctorName = "Dave",
PatientName = "Martin",
Date = new DateOnly(2023, 01, 05)
},
new()
{
Id = Guid.NewGuid().ToString(),
Id = "4575709f-cb5d-4919-9fc2-4afcf5f3c431",
DoctorName = "Steven",
PatientName = "Smith",
Date = new DateOnly(2023, 01, 10)
Expand Down
1 change: 1 addition & 0 deletions samples/Plugins/JsonPlugin/CreateJson.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ public class CreateJson : ICommand
{
public string Name => "json";
public string Description => "Outputs JSON value.";
public string Version => typeof(JsonConvert).Assembly.FullName;

private class Info
{
Expand Down
1 change: 1 addition & 0 deletions samples/Plugins/OldJsonPlugin/CreateJson.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ public class CreateJson : ICommand
{
public string Name => "oldjson";
public string Description => "Outputs JSON value.";
public string Version => typeof(JsonConvert).Assembly.FullName;

private class Info
{
Expand Down
2 changes: 1 addition & 1 deletion samples/Plugins/PersonPlugin/Example.PersonPlugin.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="SimpleResults" Version="0.3.0-alpha" />
<PackageReference Include="SimpleResults.AspNetCore" Version="0.3.0-alpha" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion samples/Plugins/PersonPlugin/PersonController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ public Result<IEnumerable<Person>> GetAll(IPersonService service)
=> service.GetAll();

[HttpPost]
public Result Create() => Result.Success();
public ActionResult<Result> Create() => Result.CreatedResource().ToActionResult();
}
38 changes: 38 additions & 0 deletions samples/Test/Example.Test.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

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

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" />
<PackageReference Include="FluentAssertions" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="NUnit" />
<PackageReference Include="NUnit3TestAdapter" />
<PackageReference Include="NUnit.Analyzers" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\HostApplications\WebApi\Example.HostWebApi.csproj" />
</ItemGroup>

<ItemGroup>
<!-- Copy the plugins directory from Example.HostWebApi to the output directory of Example.Test. -->
<Content
Include="..\HostApplications\WebApi\bin\$(Configuration)\$(TargetFramework)\plugins\**"
CopyToOutputDirectory="PreserveNewest"
TargetPath="plugins\%(RecursiveDir)\%(Filename)%(Extension)"
/>

<!-- Copy the plugins directory from Example.HostConsoleApp to the output directory of Example.Test. -->
<Content
Include="..\HostApplications\ConsoleApp\bin\$(Configuration)\$(TargetFramework)\plugins\**"
CopyToOutputDirectory="PreserveNewest"
TargetPath="plugins\%(RecursiveDir)\%(Filename)%(Extension)"
/>
</ItemGroup>

</Project>
8 changes: 8 additions & 0 deletions samples/Test/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
global using NUnit.Framework;
global using FluentAssertions;
global using Microsoft.AspNetCore.Mvc.Testing;
global using SimpleResults;
global using System.Net;
global using Example.WebApi;
global using CPlugin.Net;
global using Example.Contracts;
52 changes: 52 additions & 0 deletions samples/Test/PluginLoaderTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
namespace Example.Test;

public class PluginLoaderTest
{
private class GetPluginInfo
{
public string Name { get; set; }
public string Description { get; set; }
public string Version { get; set; }
}

[Test]
public void Load_WhenPluginsAreFound_ShouldBeLoadedIntoMemory()
{
// Arrange
var plugins =
"""
Example.JsonPlugin.dll
Example.OldJsonPlugin.dll
""";
Environment.SetEnvironmentVariable("PLUGINS", plugins);
var envConfiguration = new CPluginEnvConfiguration();
var expectedInfo = new GetPluginInfo[]
{
new()
{
Name = "json",
Description = "Outputs JSON value.",
Version = "Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed"
},
new()
{
Name = "oldjson",
Description = "Outputs JSON value.",
Version = "Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed"
}
};

// Act
PluginLoader.Load(envConfiguration);
var commands = TypeFinder.FindSubtypesOf<ICommand>();
var actualInfo = commands.Select(command => new GetPluginInfo
{
Name = command.Name,
Description = command.Description,
Version = command.Version
}).ToArray();

// Assert
actualInfo.Should().BeEquivalentTo(expectedInfo);
}
}
105 changes: 105 additions & 0 deletions samples/Test/WebApi/Get.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
namespace Example.Test.WebApi;

public class Get
{
[Test]
public async Task Get_WhenAppointmentsAreObtained_ShouldReturnsHttpStatusCodeOk()
{
// Arrange
using var factory = new WebApplicationFactory<Program>();
var client = factory.CreateClient();
int expectedAppointments = 3;

// Act
var httpResponse = await client.GetAsync("/Appointment");
var result = await httpResponse
.Content
.ReadFromJsonAsync<ListedResult<GetAppointmentResponse>>();

// Asserts
httpResponse.StatusCode.Should().Be(HttpStatusCode.OK);
result.IsSuccess.Should().BeTrue();
result.Data.Should().HaveCount(expectedAppointments);
}

[Test]
public async Task Get_WhenAppointmentIsObtained_ShouldReturnsHttpStatusCodeOk()
{
// Arrange
using var factory = new WebApplicationFactory<Program>();
var client = factory.CreateClient();
var requestUri = "/Appointment/5dace456-13d9-42c5-92ea-89869ac44b5c";

// Act
var httpResponse = await client.GetAsync(requestUri);
var result = await httpResponse
.Content
.ReadFromJsonAsync<Result<GetAppointmentResponse>>();

// Asserts
httpResponse.StatusCode.Should().Be(HttpStatusCode.OK);
result.IsSuccess.Should().BeTrue();
result.Data.Should().NotBeNull();
}

[Test]
public async Task Get_WhenAppointmentIsNotFound_ShouldReturnsHttpStatusCodeNotFound()
{
// Arrange
using var factory = new WebApplicationFactory<Program>();
var client = factory.CreateClient();
var requestUri = "/Appointment/5dace456";

// Act
var httpResponse = await client.GetAsync(requestUri);
var result = await httpResponse
.Content
.ReadFromJsonAsync<Result<GetAppointmentResponse>>();

// Asserts
httpResponse.StatusCode.Should().Be(HttpStatusCode.NotFound);
result.IsSuccess.Should().BeFalse();
result.Data.Should().BeNull();
}

[TestCase("/People")]
[TestCase("/Person")]
public async Task Get_WhenPersonsAreObtained_ShouldReturnsHttpStatusCodeOk(string requestUri)
{
// Arrange
using var factory = new WebApplicationFactory<Program>();
var client = factory.CreateClient();
int expectedPersons = 3;

// Act
var httpResponse = await client.GetAsync(requestUri);
var result = await httpResponse
.Content
.ReadFromJsonAsync<Result<IEnumerable<GetPersonResponse>>>();

// Asserts
httpResponse.StatusCode.Should().Be(HttpStatusCode.OK);
result.IsSuccess.Should().BeTrue();
result.Data.Should().HaveCount(expectedPersons);
}

[Test]
public async Task Get_WhenWeatherForecastAreObtained_ShouldReturnsHttpStatusCodeOk()
{
// Arrange
using var factory = new WebApplicationFactory<Program>();
var client = factory.CreateClient();
int expectedWeatherForecast = 5;

// Act
var httpResponse = await client.GetAsync("/WeatherForecast");
var result = await httpResponse
.Content
.ReadFromJsonAsync<ListedResult<WeatherForecast>>();

// Asserts
httpResponse.StatusCode.Should().Be(HttpStatusCode.OK);
result.IsSuccess.Should().BeTrue();
result.Data.Should().HaveCount(expectedWeatherForecast);
}
}
15 changes: 15 additions & 0 deletions samples/Test/WebApi/Models.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Example.Test.WebApi;

public class GetAppointmentResponse
{
public string Id { get; set; }
public string DoctorName { get; set; }
public string PatientName { get; set; }
}

public class GetPersonResponse
{
public int Id { get; set; }
public string Name { get; set; }
public string Document { get; set; }
}
23 changes: 23 additions & 0 deletions samples/Test/WebApi/Post.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace Example.Test.WebApi;

public class Post
{
[TestCase("/Person")]
[TestCase("/People")]
public async Task Post_WhenPersonIsCreated_ShouldReturnsHttpStatusCodeCreated(string requestUri)
{
// Arrange
using var factory = new WebApplicationFactory<Program>();
var client = factory.CreateClient();

// Act
var httpResponse = await client.PostAsJsonAsync(requestUri, new {});
var result = await httpResponse
.Content
.ReadFromJsonAsync<Result>();

// Asserts
httpResponse.StatusCode.Should().Be(HttpStatusCode.Created);
result.IsSuccess.Should().BeTrue();
}
}

0 comments on commit a7ca1ce

Please sign in to comment.