Add the ability while generating a mock to specify a file to use as the request body
This was the last real hole in the mock generation--you should now be able to generate a response for whatever endpoint you want with whatever request body and parameters you desire.
This commit is contained in:
Родитель
48390b60f5
Коммит
0a6cc307d7
24
Testing.md
24
Testing.md
|
@ -111,14 +111,16 @@ MockDataGenerator.exe, from the MockDataGenerator project, is used to target a W
|
|||
|
||||
### MockDataGenerator Parameters
|
||||
|
||||
| Parameter | Purpose |
|
||||
|-------------------------|------------------------------------------------|
|
||||
| /Address | URL for device (eg. https://10.0.0.1:11443) |
|
||||
| /User | WDP username |
|
||||
| /Pwd | WDP password |
|
||||
| /Endpoint | API to call (default is all endoints in program.cs) |
|
||||
| /Method | HTTP method to use (default is GET) |
|
||||
| /Directory | Directory to save mock data file(s) (default is .\MockData) |
|
||||
| Parameter | Purpose |
|
||||
|----------------------------|------------------------------------------------|
|
||||
| /Address | URL for device (eg. https://10.0.0.1:11443) |
|
||||
| /User | WDP username |
|
||||
| /Pwd | WDP password |
|
||||
| /Endpoint | API to call (default is all endoints in program.cs) |
|
||||
| /Method | HTTP method to use (default is GET) |
|
||||
| /Directory | Directory to save mock data file(s) (default is .\MockData) |
|
||||
| /requestBody | File to use for the request body. Only applicable when /Endpoint is present. |
|
||||
| /requestBodyMultiPartFile | Normally the requestBody file is considered JSON and provided as is. Specify this parameter to include it as a multipart file instead. |
|
||||
|
||||
### MockDataGenerator File Name Format
|
||||
|
||||
|
@ -150,6 +152,12 @@ All examples connect to 10.0.0.1:11443 with username TestUser and password Super
|
|||
```shell
|
||||
MockDataGenerator.exe /ip: 10.0.0.1:11443/user:TestUser /pwd:SuperSecret /endpoint:api/resourcemanager/systemperf /method:WebSocket
|
||||
```
|
||||
|
||||
* Generate mock for a POST call to upload a file, specifying the file to use for the request body.
|
||||
|
||||
```shell
|
||||
MockDataGenerator.exe /ip: 10.0.0.1:11443/user:TestUser /pwd:SuperSecret /endpoint:api/filesystem/apps/file?knownfolderid=LocalAppData&packagefullname=MyTestPackage_Fullname /method:Post /requestBody:myfile.txt /requestBodyMultiPartFile
|
||||
```
|
||||
|
||||
## Adding Mock Data to the Solution
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ using System;
|
|||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Tools.WindowsDevicePortal;
|
||||
|
@ -23,7 +24,7 @@ namespace MockDataGenerator
|
|||
/// <summary>
|
||||
/// Usage string
|
||||
/// </summary>
|
||||
private const string GeneralUsageMessage = "Usage: /address:<URL for device (eg. https://10.0.0.1:11443)> /user:<WDP username> /pwd:<WDP password> [/endpoint:<api to call>] [/directory:<directory to save mock data file(s)>";
|
||||
private const string GeneralUsageMessage = "Usage: /address:<URL for device (eg. https://10.0.0.1:11443)> /user:<WDP username> /pwd:<WDP password> [/endpoint:<api to call> [/method:<http method>] [/requestBody:<path to file for requestBody (PUT and POST only)>] [/requestBodyMultiPartFile (otherwise defaults to application/json] [/directory:<directory to save mock data file(s)>";
|
||||
|
||||
/// <summary>
|
||||
/// Endpoints for REST calls to populate. Feel free to override this list (especially locally) to
|
||||
|
@ -137,8 +138,47 @@ namespace MockDataGenerator
|
|||
|
||||
string endpoint = parameters.GetParameterValue("endpoint");
|
||||
|
||||
Task saveResponseTask = portal.SaveEndpointResponseToFile(endpoint, directory, httpMethod);
|
||||
saveResponseTask.Wait();
|
||||
string requestBodyFile = parameters.GetParameterValue("requestbody");
|
||||
|
||||
if (!string.IsNullOrEmpty(requestBodyFile))
|
||||
{
|
||||
if (parameters.HasFlag("requestbodymultipartfile"))
|
||||
{
|
||||
string boundaryString = Guid.NewGuid().ToString();
|
||||
|
||||
using (MemoryStream dataStream = new MemoryStream())
|
||||
{
|
||||
byte[] data;
|
||||
|
||||
FileInfo fi = new FileInfo(requestBodyFile);
|
||||
data = Encoding.ASCII.GetBytes(string.Format("\r\n--{0}\r\n", boundaryString));
|
||||
dataStream.Write(data, 0, data.Length);
|
||||
CopyFileToRequestStream(fi, dataStream);
|
||||
|
||||
// Close the multipart request data.
|
||||
data = Encoding.ASCII.GetBytes(string.Format("\r\n--{0}--\r\n", boundaryString));
|
||||
dataStream.Write(data, 0, data.Length);
|
||||
|
||||
dataStream.Position = 0;
|
||||
string contentType = string.Format("multipart/form-data; boundary={0}", boundaryString);
|
||||
|
||||
Task saveResponseTask = portal.SaveEndpointResponseToFile(endpoint, directory, httpMethod, dataStream, contentType);
|
||||
saveResponseTask.Wait();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Stream fileStream = new FileStream(requestBodyFile, FileMode.Open);
|
||||
|
||||
Task saveResponseTask = portal.SaveEndpointResponseToFile(endpoint, directory, httpMethod, fileStream, "application/json");
|
||||
saveResponseTask.Wait();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Task saveResponseTask = portal.SaveEndpointResponseToFile(endpoint, directory, httpMethod);
|
||||
saveResponseTask.Wait();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -184,6 +224,32 @@ namespace MockDataGenerator
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies a file to the specified stream and prepends the necessary content information
|
||||
/// required to be part of a multipart form data request.
|
||||
/// </summary>
|
||||
/// <param name="file">The file to be copied.</param>
|
||||
/// <param name="stream">The stream to which the file will be copied.</param>
|
||||
private static void CopyFileToRequestStream(
|
||||
FileInfo file,
|
||||
Stream stream)
|
||||
{
|
||||
byte[] data;
|
||||
string contentDisposition = string.Format("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n", file.Name, file.Name);
|
||||
string contentType = "Content-Type: application/octet-stream\r\n\r\n";
|
||||
|
||||
data = Encoding.ASCII.GetBytes(contentDisposition);
|
||||
stream.Write(data, 0, data.Length);
|
||||
|
||||
data = Encoding.ASCII.GetBytes(contentType);
|
||||
stream.Write(data, 0, data.Length);
|
||||
|
||||
using (FileStream fs = File.OpenRead(file.FullName))
|
||||
{
|
||||
fs.CopyTo(stream);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encapsulation of an endpoint and its HTTP method.
|
||||
/// </summary>
|
||||
|
|
|
@ -5,9 +5,12 @@
|
|||
//----------------------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
#if !WINDOWS_UWP
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
#endif // !WINDOWS_UWP
|
||||
#if WINDOWS_UWP
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
|
@ -20,6 +23,7 @@ using System.Threading.Tasks;
|
|||
#if WINDOWS_UWP
|
||||
using Windows.Security.Cryptography.Certificates;
|
||||
using Windows.Web.Http;
|
||||
using Windows.Web.Http.Headers;
|
||||
#endif // WINDOWS_UWP
|
||||
|
||||
namespace Microsoft.Tools.WindowsDevicePortal
|
||||
|
@ -305,8 +309,15 @@ namespace Microsoft.Tools.WindowsDevicePortal
|
|||
/// <param name="endpoint">API endpoint we are calling.</param>
|
||||
/// <param name="directory">Directory to store our file.</param>
|
||||
/// <param name="httpMethod">The http method to be performed.</param>
|
||||
/// <param name="requestBody">An optional stream to use for the request body content.</param>
|
||||
/// <param name="requestBodyContentType">The content type of the request stream.</param>
|
||||
/// <returns>Task waiting for HTTP call to return and file copy to complete.</returns>
|
||||
public async Task SaveEndpointResponseToFile(string endpoint, string directory, HttpMethods httpMethod)
|
||||
public async Task SaveEndpointResponseToFile(
|
||||
string endpoint,
|
||||
string directory,
|
||||
HttpMethods httpMethod,
|
||||
Stream requestBody = null,
|
||||
string requestBodyContentType = null)
|
||||
{
|
||||
Uri uri = new Uri(this.deviceConnection.Connection, endpoint);
|
||||
|
||||
|
@ -376,7 +387,24 @@ namespace Microsoft.Tools.WindowsDevicePortal
|
|||
}
|
||||
else if (HttpMethods.Put == httpMethod)
|
||||
{
|
||||
using (Stream dataStream = await this.Put(uri))
|
||||
#if WINDOWS_UWP
|
||||
HttpStreamContent streamContent = null;
|
||||
#else
|
||||
StreamContent streamContent = null;
|
||||
#endif // WINDOWS_UWP
|
||||
|
||||
if (requestBody != null)
|
||||
{
|
||||
#if WINDOWS_UWP
|
||||
streamContent = new HttpStreamContent(requestBody.AsInputStream());
|
||||
streamContent.Headers.ContentType = new HttpMediaTypeHeaderValue(requestBodyContentType);
|
||||
#else
|
||||
streamContent = new StreamContent(requestBody);
|
||||
streamContent.Headers.ContentType = new MediaTypeHeaderValue(requestBodyContentType);
|
||||
#endif // WINDOWS_UWP
|
||||
}
|
||||
|
||||
using (Stream dataStream = await this.Put(uri, streamContent))
|
||||
{
|
||||
using (var fileStream = File.Create(filepath))
|
||||
{
|
||||
|
@ -387,7 +415,7 @@ namespace Microsoft.Tools.WindowsDevicePortal
|
|||
}
|
||||
else if (HttpMethods.Post == httpMethod)
|
||||
{
|
||||
using (Stream dataStream = await this.Post(uri))
|
||||
using (Stream dataStream = await this.Post(uri, requestBody, requestBodyContentType))
|
||||
{
|
||||
using (var fileStream = File.Create(filepath))
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче