Skip to content

Commit

Permalink
Added request and response processors that ensures they are not null (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
david-driscoll authored Jul 28, 2020
1 parent f93f973 commit 7d4ecc5
Show file tree
Hide file tree
Showing 20 changed files with 76 additions and 13 deletions.
17 changes: 17 additions & 0 deletions src/JsonRpc/Pipelines/RequestMustNotBeNullProcessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace OmniSharp.Extensions.JsonRpc.Pipelines
{
public class RequestMustNotBeNullProcessor<T> : MediatR.Pipeline.IRequestPreProcessor<T>
{
public Task Process(T request, CancellationToken cancellationToken)
{
if (typeof(T).IsClass && EqualityComparer<T>.Default.Equals(request, default))
throw new ArgumentNullException(nameof(request), $"Pipeline request ({typeof(T).FullName}) must not be null");
return Task.CompletedTask;
}
}
}
17 changes: 17 additions & 0 deletions src/JsonRpc/Pipelines/ResponseMustNotBeNullProcessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace OmniSharp.Extensions.JsonRpc.Pipelines
{
public class ResponseMustNotBeNullProcessor<T, R> : MediatR.Pipeline.IRequestPostProcessor<T, R>
{
public Task Process(T request, R response, CancellationToken cancellationToken)
{
if (typeof(R).IsClass && EqualityComparer<R>.Default.Equals(response, default))
throw new ArgumentNullException(nameof(request), $"Pipeline response ({typeof(R).FullName}) must not be null");
return Task.CompletedTask;
}
}
}
11 changes: 6 additions & 5 deletions src/JsonRpc/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
using System.Collections.Generic;
using System.Reflection;
using MediatR;
using MediatR.Pipeline;
using MediatR.Registration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using OmniSharp.Extensions.JsonRpc.Pipelines;

namespace OmniSharp.Extensions.JsonRpc
{
Expand All @@ -14,13 +16,11 @@ public static IServiceCollection AddJsonRpcMediatR(this IServiceCollection servi
{
ServiceRegistrar.AddRequiredServices(services, new MediatRServiceConfiguration());
ServiceRegistrar.AddMediatRClasses(services, assemblies);
services.AddTransient(typeof(IRequestPreProcessor<>), typeof(RequestMustNotBeNullProcessor<>));
services.AddTransient(typeof(IRequestPostProcessor<,>), typeof(ResponseMustNotBeNullProcessor<,>));
services.AddScoped<IRequestContext, RequestContext>();
services.RemoveAll<ServiceFactory>();
services.AddScoped<ServiceFactory>(
serviceProvider => {
return serviceType => GetHandler(serviceProvider, serviceType);
}
);
services.AddScoped<ServiceFactory>(serviceProvider => { return serviceType => GetHandler(serviceProvider, serviceType); });
return services;
}

Expand All @@ -32,6 +32,7 @@ private static object GetHandler(IServiceProvider serviceProvider, Type serviceT
var context = serviceProvider.GetService<IRequestContext>();
return context.Descriptor != null ? context.Descriptor.Handler : serviceProvider.GetService(serviceType);
}

return serviceProvider.GetService(serviceType);
}
}
Expand Down
36 changes: 36 additions & 0 deletions test/JsonRpc.Tests/IntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Threading;
using System.Threading.Tasks;
using FluentAssertions;
using MediatR;
using OmniSharp.Extensions.JsonRpc;
using OmniSharp.Extensions.JsonRpc.Server;
using OmniSharp.Extensions.JsonRpc.Testing;
Expand All @@ -17,6 +18,11 @@ public IntegrationTests() : base(new JsonRpcTestOptions())
{
}

class Request : IRequest<Data>
{

}

class Data
{
public string Value { get; set; }
Expand All @@ -37,6 +43,36 @@ public async Task Should_Send_and_receive_requests()
clientResponse.Value.Should().Be("myresponse");
}

[Fact]
public async Task Should_throw_when_sending_requests()
{
var (client, server) = await Initialize(
client => { client.OnRequest("myrequest", async (Request request) => new Data() {Value = "myresponse"}); },
server => { server.OnRequest("myrequest", async (Request request) => new Data() {Value = string.Join("", "myresponse".Reverse())}); }
);

Func<Task> clientRequest = () => client.SendRequest("myrequest", (Request)null).Returning<Data>(CancellationToken);
clientRequest.Should().Throw<InvalidParametersException>();

Func<Task> serverRequest = () => server.SendRequest("myrequest", (Request)null).Returning<Data>(CancellationToken);
serverRequest.Should().Throw<InvalidParametersException>();
}

[Fact]
public async Task Should_throw_when_receiving_requests()
{
var (client, server) = await Initialize(
client => { client.OnRequest("myrequest", async (Request request) => (Data)null); },
server => { server.OnRequest("myrequest", async (Request request) => (Data)null); }
);

Func<Task> clientRequest = () => client.SendRequest("myrequest", new Request()).Returning<Data>(CancellationToken);
clientRequest.Should().Throw<InternalErrorException>();

Func<Task> serverRequest = () => server.SendRequest("myrequest", new Request()).Returning<Data>(CancellationToken);
serverRequest.Should().Throw<InternalErrorException>();
}

[Fact]
public async Task Should_Send_and_receive_notifications()
{
Expand Down
Empty file.
1 change: 0 additions & 1 deletion test/coverage/Client-Tests/coverage.netcoreapp2.1.json

This file was deleted.

Empty file.
1 change: 0 additions & 1 deletion test/coverage/Client-Tests/coverage.netcoreapp3.1.json

This file was deleted.

Empty file.
1 change: 0 additions & 1 deletion test/coverage/Dap-Tests/coverage.netcoreapp2.1.json

This file was deleted.

Empty file.
1 change: 0 additions & 1 deletion test/coverage/Dap-Tests/coverage.netcoreapp3.1.json

This file was deleted.

Empty file.
1 change: 0 additions & 1 deletion test/coverage/Generation-Tests/coverage.netcoreapp2.1.json

This file was deleted.

Empty file.
1 change: 0 additions & 1 deletion test/coverage/Generation-Tests/coverage.netcoreapp3.1.json

This file was deleted.

Empty file.
1 change: 0 additions & 1 deletion test/coverage/JsonRpc-Tests/coverage.netcoreapp2.1.json

This file was deleted.

Empty file.
1 change: 0 additions & 1 deletion test/coverage/JsonRpc-Tests/coverage.netcoreapp3.1.json

This file was deleted.

0 comments on commit 7d4ecc5

Please sign in to comment.