[265] Add file upload to allow mocking of file operations (#266)

* [265] Add file upload to allow mocking of file operations

* [265] Fix failing test

* Update code + add tests

* LocalFileSystemHandlerTests

* 1.0.13

* Fixed the file post to create the mapping folder if none exists to begin with, otherwise the file upload fails with 404 (can't find the folder to upload to).

* fix tests

* add more tests for LocalFileSystemHandler

* Added the head method for files to check if a file exists without returning it as a body.

* Add a test and fix the response message (head requires no body).

* Fix newline

* Fix newline.

* Fix the number of mapping tests

* Update tests and update client-interface-api

* Cleanup "MappingConverter.cs"
This commit is contained in:
JackCreativeCrew
2019-04-11 16:46:14 +10:00
committed by Stef Heyenrath
parent 6c32b9c31a
commit 12444cc11e
17 changed files with 850 additions and 37 deletions

View File

@@ -34,13 +34,14 @@ namespace WireMock.Server
private const int AdminPriority = int.MinValue;
private const int ProxyPriority = 1000;
private const string ContentTypeJson = "application/json";
private const string AdminFiles = "/__admin/files";
private const string AdminMappings = "/__admin/mappings";
private const string AdminRequests = "/__admin/requests";
private const string AdminSettings = "/__admin/settings";
private const string AdminScenarios = "/__admin/scenarios";
private readonly RegexMatcher _adminMappingsGuidPathMatcher = new RegexMatcher(MatchBehaviour.AcceptOnMatch, @"^\/__admin\/mappings\/(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$");
private readonly RegexMatcher _adminRequestsGuidPathMatcher = new RegexMatcher(MatchBehaviour.AcceptOnMatch, @"^\/__admin\/requests\/(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$");
private readonly RegexMatcher _adminMappingsGuidPathMatcher = new RegexMatcher(MatchBehaviour.AcceptOnMatch, @"^\/__admin\/mappings\/([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12})$");
private readonly RegexMatcher _adminRequestsGuidPathMatcher = new RegexMatcher(MatchBehaviour.AcceptOnMatch, @"^\/__admin\/requests\/([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12})$");
private readonly JsonSerializerSettings _settings = new JsonSerializerSettings
{
@@ -97,10 +98,17 @@ namespace WireMock.Server
// __admin/scenarios/reset
Given(Request.Create().WithPath(AdminScenarios + "/reset").UsingPost()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(ScenariosReset));
// __admin/files/{filename}
Given(Request.Create().WithPath(_adminFilesFilenamePathMatcher).UsingPost()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(FilePost));
Given(Request.Create().WithPath(_adminFilesFilenamePathMatcher).UsingPut()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(FilePut));
Given(Request.Create().WithPath(_adminFilesFilenamePathMatcher).UsingGet()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(FileGet));
Given(Request.Create().WithPath(_adminFilesFilenamePathMatcher).UsingHead()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(FileHead));
Given(Request.Create().WithPath(_adminFilesFilenamePathMatcher).UsingDelete()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(FileDelete));
}
#endregion
#region StaticMappings
#region StaticMappings
/// <summary>
/// Saves the static mappings.
/// </summary>

View File

@@ -0,0 +1,114 @@
using System.IO;
using System.Linq;
using System.Text;
using WireMock.Matchers;
using WireMock.Util;
namespace WireMock.Server
{
public partial class FluentMockServer
{
private readonly RegexMatcher _adminFilesFilenamePathMatcher = new RegexMatcher(MatchBehaviour.AcceptOnMatch, @"^\/__admin\/files\/.*$");
private static readonly Encoding[] FileBodyIsString = { Encoding.UTF8, Encoding.ASCII };
#region Files/{filename}
private ResponseMessage FilePost(RequestMessage requestMessage)
{
string filename = GetFileNameFromRequestMessage(requestMessage);
string mappingFolder = _fileSystemHandler.GetMappingFolder();
if (!_fileSystemHandler.FolderExists(mappingFolder))
{
_fileSystemHandler.CreateFolder(mappingFolder);
}
_fileSystemHandler.WriteFile(filename, requestMessage.BodyAsBytes);
return ResponseMessageBuilder.Create("File created");
}
private ResponseMessage FilePut(RequestMessage requestMessage)
{
string filename = GetFileNameFromRequestMessage(requestMessage);
if (!_fileSystemHandler.FileExists(filename))
{
_logger.Info("The file '{0}' does not exist, updating file will be skipped.", filename);
return ResponseMessageBuilder.Create("File is not found", 404);
}
_fileSystemHandler.WriteFile(filename, requestMessage.BodyAsBytes);
return ResponseMessageBuilder.Create("File updated");
}
private ResponseMessage FileGet(RequestMessage requestMessage)
{
string filename = GetFileNameFromRequestMessage(requestMessage);
if (!_fileSystemHandler.FileExists(filename))
{
_logger.Info("The file '{0}' does not exist.", filename);
return ResponseMessageBuilder.Create("File is not found", 404);
}
byte[] bytes = _fileSystemHandler.ReadFile(filename);
var response = new ResponseMessage
{
StatusCode = 200,
BodyData = new BodyData
{
BodyAsBytes = bytes,
DetectedBodyType = BodyType.Bytes,
DetectedBodyTypeFromContentType = BodyType.None
}
};
if (BytesEncodingUtils.TryGetEncoding(bytes, out Encoding encoding) && FileBodyIsString.Select(x => x.Equals(encoding)).Any())
{
response.BodyData.DetectedBodyType = BodyType.String;
response.BodyData.BodyAsString = encoding.GetString(bytes);
}
return response;
}
/// <summary>
/// Checks if file exists.
/// Note: Response is returned with no body as a head request doesn't accept a body, only the status code.
/// </summary>
/// <param name="requestMessage">The request message.</param>
private ResponseMessage FileHead(RequestMessage requestMessage)
{
string filename = GetFileNameFromRequestMessage(requestMessage);
if (!_fileSystemHandler.FileExists(filename))
{
_logger.Info("The file '{0}' does not exist.", filename);
return ResponseMessageBuilder.Create(404);
}
return ResponseMessageBuilder.Create(204);
}
private ResponseMessage FileDelete(RequestMessage requestMessage)
{
string filename = GetFileNameFromRequestMessage(requestMessage);
if (!_fileSystemHandler.FileExists(filename))
{
_logger.Info("The file '{0}' does not exist.", filename);
return ResponseMessageBuilder.Create("File is not deleted", 404);
}
_fileSystemHandler.DeleteFile(filename);
return ResponseMessageBuilder.Create("File deleted.");
}
private string GetFileNameFromRequestMessage(RequestMessage requestMessage)
{
return Path.GetFileName(requestMessage.Path.Substring(AdminFiles.Length + 1));
}
#endregion
}
}