Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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();
}
}