MyDaftQuestions
MyDaftQuestions

Reputation: 4701

How do I replicate HttpRequest

PayPal have provided example code how to receive a notification of a purchase (or similar). Sadly, I don't see a way to manually test this and I'm struggling to see how to replicate Microsoft.AspNetCore.Http HttpRequest

https://github.com/paypal/ipn-code-samples/tree/master/C%23

The relevant part of the code is

[HttpPost]
public IActionResult Receive()
{
    IPNContext ipnContext = new IPNContext()
    {
        IPNRequest = Request      //IPNRequest is HttpRequest 
    };

    using (var reader = new StreamReader(ipnContext.IPNRequest.Body, Encoding.ASCII))
    {
        ipnContext.RequestBody = await reader.ReadToEndAsync();
    }
    //other code removed for this example
}

What I'd like to do is replicate request so I can execute this from a test! Normally, I'd refactor the code so I can pass parameters to get around this issue (even if I pass in the rendered string).

In this instance, I want to pretend I can't touch the source code, but still need to test it. This is so I can learn more.

As the bit I am after is the stream, as seen in ipnContext.IPNRequest.Body, I'm stumped. If it's a stream, I can't assign it as a string, but when it does the ReadToEndAsync, a string comes out!

How do I create the Request object with a similar shape to what PayPal expects for Request.IPNRequest.Body

Upvotes: 0

Views: 224

Answers (1)

Nkosi
Nkosi

Reputation: 247521

Arrange a stream as needed and pass that to the controller via the HttpContext.Request

[TestMethod]
public Task Should_Receive() {
    //Arrange
    var data = "My paypal expected string here";
    var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(data));

    HttpContext httpContext = new DefaultHttpContext();
    httpContext.Request.Body = stream; //<-- Setting request BODY here
    httpContext.Request.ContentLength = stream.Length;

    var controller = new IPNController {
        ControllerContext = new ControllerContext() {
            HttpContext = httpContext,
        }
    };

    //Act
    IActionResult result = await controller.Receive();

    //Assert
    //assert as needed
}

The sample code linked to your original example is tightly coupled to external dependencies and may have other issues that are outside of the scope of what was originally asked.

Upvotes: 3

Related Questions