namespace ProtoTest.Demo;
using global::Grpc.Core;
using global::NUnit.Framework;
using Google.Protobuf;
using Northstar.ProtoTest;
using ProtoTest.Core;
using ProtoTest.Data;
using ProtoTest.Grpc;
using ProtoTest.Http;
using ProtoTest.NUnit;
using ProtoTest.SampleApp.Contracts;
using ProtoTest.SampleApp.Domain;
using ProtoTest.SampleApp.Grpc;
///
/// The same application over gRPC: the shared [Auth] bearer token travels as metadata, the call
/// is traced as a grpc.call span, and the reply is asserted like any other value.
///
[Application(NorthstarTargets.Api)]
[NorthstarTenant(PlanIds.Growth)]
[Auth]
public sealed class GrpcJourney
{
private static readonly Marshaller GetRequestMarshaller = Marshallers.Create(
(request, context) => context.Complete(request.ToByteArray()),
context => GetProjectRequest.Parser.ParseFrom(context.PayloadAsNewBuffer()));
private static readonly Marshaller ListRequestMarshaller = Marshallers.Create(
(request, context) => context.Complete(request.ToByteArray()),
context => ListProjectsRequest.Parser.ParseFrom(context.PayloadAsNewBuffer()));
private static readonly Marshaller ReplyMarshaller = Marshallers.Create(
(reply, context) => context.Complete(reply.ToByteArray()),
context => ProjectReply.Parser.ParseFrom(context.PayloadAsNewBuffer()));
private static readonly Method GetProjectMethod = new(
MethodType.Unary, "northstar.v1.Projects", "GetProject", GetRequestMarshaller, ReplyMarshaller);
private static readonly Method ListProjectsMethod = new(
MethodType.ServerStreaming, "northstar.v1.Projects", "ListProjects", ListRequestMarshaller, ReplyMarshaller);
[ProtoTest]
[SignedInAs]
public async Task AProjectIsReadableOverGrpc()
{
// Arrange over the API, read back over gRPC.
var project = await Proto.Context.Data()
.For()
.With(request => request.Name, "grpc-atlas")
.CreateAsync();
// Act: unary, then the server stream.
var client = Proto.Context.Grpc();
var reply = await client.UnaryAsync(GetProjectMethod, new GetProjectRequest { ProjectId = project.Id });
var listed = await client.ServerStreamingAsync(
ListProjectsMethod,
new ListProjectsRequest { Limit = 10 });
// Assert: same identity, same state, from the other protocol.
Assert.Multiple(() =>
{
reply.ShouldMatchShape(new
{
id = project.Id,
name = "grpc-atlas",
status = ProjectStatuses.Active
});
Assert.That(listed.Any(item => item.Id == project.Id), Is.True,
"The project created over REST is visible on the gRPC stream.");
});
}
}