我正在研究MoveIt应用程序接口以及如何使用C#代码来使用它。尝试查找一些基于https://docs.ipswitch.com/MOVEit/Transfer2020/API/rest/#operation/POSTapi%2Fv1%2Ffolders%2F%7BId%7D%2Fsubfolders-1.0或https://docs.ipswitch.com/MOVEit/Transfer2019_1/API/Rest/的示例代码MoveIt也有一个“REST API Swagger用户界面”
另外,我想使用.NET内核。我环顾四周,没有找到很多东西,最终开始构建一个,现在我已经分享了它。
发布于 2021-06-30 09:32:46
我做了大量的研究和试验,最终我能够写出一个可测试的代码,我认为我可以分享。这是一些示例代码,我将模型类放在这里,这些模型类基于https://docs.ipswitch.com/MOVEit/Transfer2019_1/API/Rest/和MoveIt的REST API Swagger用户界面,它使用HttpClient和HtttpClient工厂。还在两个部分中添加了自动化单元测试的代码。
//You need Following package
Microsoft.Extension.http
System.Net.Http
System.Net.Http.Json
///////////////////FTPException class
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;
namespace FtpUtilityLib.Exceptions
{
[ExcludeFromCodeCoverage]
[Serializable]
public class FtpException : Exception
{
public FtpException()
{
}
public FtpException(string message) : base(message)
{
}
public FtpException(string message, Exception inner) : base(message, inner)
{
}
protected FtpException(
SerializationInfo info,
StreamingContext context) : base(info, context)
{
}
}
}
//////////////// Models
using System.Text.Json.Serialization;
namespace FtpUtilityLib.Models
{
public class AuthError
{
[JsonPropertyName("error")]
public string Error { get; set; }
[JsonPropertyName("error_description")]
public string ErrorDescription { get; set; }
}
public class Error
{
[JsonPropertyName("detail")]
public string Detail { get; set; }
[JsonPropertyName("errorCode")]
public int ErrorCode { get; set; }
[JsonPropertyName("title")]
public string Title { get; set; }
}
public class FileItem
{
[JsonPropertyName("uploadUsername")]
public string UploadUsername { get; set; }
[JsonPropertyName("uploadAgentVersion")]
public string UploadAgentVersion { get; set; }
[JsonPropertyName("currentFileType")]
public string CurrentFileType { get; set; }
[JsonPropertyName("hash")]
public string Hash { get; set; }
[JsonPropertyName("dlpMetaData")]
public int DlpMetaData { get; set; }
[JsonPropertyName("dlpChecked")]
public bool DlpChecked { get; set; }
[JsonPropertyName("id")]
public string Id { get; set; }
[JsonPropertyName("dlpBlocked")]
public bool DlpBlocked { get; set; }
[JsonPropertyName("originalFileType")]
public string OriginalFileType { get; set; }
[JsonPropertyName("folderID")]
public string FolderID { get; set; }
[JsonPropertyName("uploadComment")]
public string UploadComment { get; set; }
[JsonPropertyName("uploadStamp")]
public string UploadStamp { get; set; }
[JsonPropertyName("uploadIntegrity")]
public int UploadIntegrity { get; set; }
[JsonPropertyName("name")]
public string Name { get; set; }
[JsonPropertyName("size")]
public int Size { get; set; }
[JsonPropertyName("isNew")]
public bool IsNew { get; set; }
[JsonPropertyName("uploadIP")]
public string UploadIP { get; set; }
[JsonPropertyName("path")]
public string Path { get; set; }
[JsonPropertyName("downloadCount")]
public int DownloadCount { get; set; }
[JsonPropertyName("originalFilename")]
public string OriginalFilename { get; set; }
[JsonPropertyName("orgID")]
public string OrgID { get; set; }
[JsonPropertyName("dlpViolation")]
public string DlpViolation { get; set; }
[JsonPropertyName("uploadAgentBrand")]
public string UploadAgentBrand { get; set; }
[JsonPropertyName("uploadUserFullName")]
public string UploadUserFullName { get; set; }
}
public class FileList
{
[JsonPropertyName("items")]
public List<FileItem> Items { get; set; }
[JsonPropertyName("sorting")]
public List<Sorting> Sorting { get; set; }
[JsonPropertyName("paging")]
public Paging Paging { get; set; }
}
public class FolderItem
{
[JsonPropertyName("subfolderCount")]
public int SubfolderCount { get; set; }
[JsonPropertyName("sharedWithGroupsCount")]
public int SharedWithGroupsCount { get; set; }
[JsonPropertyName("sharedWithUsersCount")]
public int SharedWithUsersCount { get; set; }
[JsonPropertyName("isShared")]
public bool IsShared { get; set; }
[JsonPropertyName("id")]
public string Id { get; set; }
[JsonPropertyName("parentId")]
public string ParentId { get; set; }
[JsonPropertyName("path")]
public string Path { get; set; }
[JsonPropertyName("lastContentChangeTime")]
public string LastContentChangeTime { get; set; }
[JsonPropertyName("permission")]
public Permission Permission { get; set; }
[JsonPropertyName("folderType")]
public string FolderType { get; set; }
[JsonPropertyName("name")]
public string Name { get; set; }
[JsonPropertyName("totalFileCount")]
public int TotalFileCount { get; set; }
}
public class Permission
{
[JsonPropertyName("canListSubfolders")]
public bool CanListSubfolders { get; set; }
[JsonPropertyName("canListFiles")]
public bool CanListFiles { get; set; }
[JsonPropertyName("canChangeSettings")]
public bool CanChangeSettings { get; set; }
[JsonPropertyName("canWriteFiles")]
public bool CanWriteFiles { get; set; }
[JsonPropertyName("canAddSubfolders")]
public bool CanAddSubfolders { get; set; }
[JsonPropertyName("canDelete")]
public bool CanDelete { get; set; }
[JsonPropertyName("canReadFiles")]
public bool CanReadFiles { get; set; }
[JsonPropertyName("canDeleteFiles")]
public bool CanDeleteFiles { get; set; }
[JsonPropertyName("canShare")]
public bool CanShare { get; set; }
}
public class FolderList
{
[JsonPropertyName("paging")]
public Paging Paging { get; set; }
[JsonPropertyName("sorting")]
public List<Sorting> Sorting { get; set; }
[JsonPropertyName("items")]
public List<FolderItem> Items { get; set; }
}
public class Paging
{
[JsonPropertyName("totalPages")]
public int TotalPages { get; set; }
[JsonPropertyName("page")]
public int Page { get; set; }
[JsonPropertyName("totalItems")]
public int TotalItems { get; set; }
[JsonPropertyName("perPage")]
public int PerPage { get; set; }
}
public class Sorting
{
[JsonPropertyName("sortField")]
public string SortField { get; set; }
[JsonPropertyName("sortDirection")]
public string SortDirection { get; set; }
}
public class Token
{
[JsonPropertyName("token_type")]
public string TokenType { get; set; }
[JsonPropertyName("access_token")]
public string AccessToken { get; set; }
[JsonPropertyName("refresh_token")]
public string RefreshToken { get; set; }
[JsonPropertyName("expires_in")]
public int ExpiresIn { get; set; }
}
public class UnprocessableEntityError
{
[JsonPropertyName("detail")]
public string Detail { get; set; }
[JsonPropertyName("errors")]
public List<SemanticError> SemanticErrors { get; set; }
[JsonPropertyName("title")]
public string Title { get; set; }
[JsonPropertyName("errorCode")]
public int ErrorCode { get; set; }
}
public class SemanticError
{
[JsonPropertyName("field")]
public string Field { get; set; }
[JsonPropertyName("message")]
public string Message { get; set; }
[JsonPropertyName("rejected")]
public string Rejected { get; set; }
}
}
/////////////////////// FtpServiceGateway class
using FtpUtilityLib.Exceptions;
using FtpUtilityLib.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
[assembly: InternalsVisibleTo("MoveItRestApiUtilityLib.Tests")]
namespace FtpUtilityLib
{
internal sealed class FtpApiServiceGateway : IDisposable
{
private const string FtpApiVersionPath = @"api/v1/";
private readonly IHttpClientFactory httpClientFactory;
private bool disposed = false;
public FtpApiServiceGateway(FtpConfiguration ftpConfiguration, IHttpClientFactory httpClientFactory)
{
FtpConfiguration = ftpConfiguration;
this.httpClientFactory = httpClientFactory;
}
public FtpConfiguration FtpConfiguration { get; }
public string AccessToken { get; private set; }
public async Task SignOnToHostAsync()
{
try
{
var httpClient = CreateHttpClient();
var formContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", FtpConfiguration.Username),
new KeyValuePair<string, string>("password", FtpConfiguration.Password),
});
var httpResponse = await httpClient.PostAsync("token", formContent);
await EnsureSignOnSuccessAsync(httpResponse);
var token = await httpResponse.Content.ReadFromJsonAsync<Token>();
AccessToken = token.AccessToken;
}
catch (Exception e)
{
throw new FtpException($"Error in logging to FTP server {FtpConfiguration.Host}. " + e.Message, e);
}
}
public async Task<string> DownloadFileAsync(
string nameOfFileToBeDownloaded,
string localFolderPath,
string localFileName)
{
var downloadedFileId = string.Empty;
try
{
using var httpClient = CreateHttpClient();
var files = await httpClient.GetFromJsonAsync<FileList>("files?perpage=100");
FileItem file = null;
for (int i = 1; i <= files.Paging.TotalPages; i++)
{
files = await httpClient.GetFromJsonAsync<FileList>($"files?perpage=100&page={i}");
file = files.Items.FirstOrDefault(x =>
x.Name.ToLower().Equals(nameOfFileToBeDownloaded.ToLower(), StringComparison.CurrentCulture));
if (file != null)
{
break;
}
}
downloadedFileId = await SendFileDownloadRequestAsync(nameOfFileToBeDownloaded, localFolderPath, localFileName, file, httpClient, string.Empty);
}
catch (Exception e)
{
throw new FtpException($"Error in downloading the file {nameOfFileToBeDownloaded} from FTP server. " + e.Message, e);
}
return downloadedFileId;
}
public async Task<string> DownloadFileAsync(
string nameOfFileToBeDownloaded,
string downloadFilePath,
string localFolderPath,
string localFileName)
{
var downloadedFileId = string.Empty;
try
{
using var httpClient = CreateHttpClient();
var folders = await httpClient.GetFromJsonAsync<FolderList>(@$"folders?path={downloadFilePath}");
var folder = folders.Items.SingleOrDefault(x => x.Path.ToLower().Equals(downloadFilePath.ToLower()));
if (folder != null)
{
var files = await httpClient.GetFromJsonAsync<FileList>($"folders/{folder.Id}/files?perPage=100");
var file = files.Items.SingleOrDefault(x =>
x.Name.ToLower().Equals(nameOfFileToBeDownloaded.ToLower(), StringComparison.CurrentCulture));
downloadedFileId = await SendFileDownloadRequestAsync(nameOfFileToBeDownloaded, localFolderPath, localFileName, file, httpClient, downloadFilePath);
}
else
{
throw new FtpException($"Folder {downloadFilePath} not found on FTP server");
}
}
catch (Exception e)
{
throw new FtpException($"Error in downloading the file {nameOfFileToBeDownloaded} from FTP server. " + e.Message, e);
}
return downloadedFileId;
}
public async Task<string> UploadFile(string sourceFilePathName, string destinationPath)
{
return await UploadFileAsync(sourceFilePathName, destinationPath, "Comments are not provided");
}
public async Task<string> UploadFileAsync(string sourceFilePathName, string destinationPath, string comments)
{
string uploadedFileId;
try
{
using var multipartFormContent = new MultipartFormDataContent();
using (var sha256 = SHA256.Create())
{
await using var fileStream = File.Open(sourceFilePathName, FileMode.Open);
// Be sure it's positioned to the beginning of the stream.
fileStream.Position = 0;
// Compute the hash of the fileStream.
byte[] hashValue = sha256.ComputeHash(fileStream);
var hash = System.Text.Encoding.UTF8.GetString(hashValue, 0, hashValue.Length);
multipartFormContent.Add(new StringContent("hash"), hash);
multipartFormContent.Add(new StringContent("hashtype"), "sha-256");
multipartFormContent.Add(new StringContent("comments"), comments);
// Close the file.
fileStream.Close();
}
await using (var fileStream = File.OpenRead(sourceFilePathName))
{
using var httpClient = CreateHttpClient();
var folders = await httpClient.GetFromJsonAsync<FolderList>(@$"folders?path={destinationPath}");
var folder = folders.Items.SingleOrDefault(x => x.Path.ToLower().Equals(destinationPath.ToLower()));
if (folder != null)
{
multipartFormContent.Add(new StreamContent(fileStream), "file", Path.GetFileName(sourceFilePathName));
var response = await httpClient.PostAsync($"folders/{folder.Id}/files", multipartFormContent);
await EnsureSuccessAsync(response);
var file = await response.Content.ReadFromJsonAsync<FileItem>();
uploadedFileId = file.Id;
}
else
{
throw new FtpException($"Folder {destinationPath} not found on FTP server");
}
fileStream.Close();
}
}
catch (Exception e)
{
throw new FtpException($"Error in Uploading the file {sourceFilePathName} to the folder {destinationPath} on FTP server. " + e.Message, e);
}
return uploadedFileId;
}
public async Task<string> UploadFileFromBufferAsync(byte[] buffer, string destinationPath, string fileName, string comments)
{
string uploadedFileId;
try
{
using var multipartFormContent = new MultipartFormDataContent();
using var sha256 = SHA256.Create();
// Compute the hash of the fileStream.
byte[] hashValue = sha256.ComputeHash(buffer);
var hash = Encoding.UTF8.GetString(hashValue, 0, hashValue.Length);
multipartFormContent.Add(new StringContent("hash"), hash);
multipartFormContent.Add(new StringContent("hashtype"), "sha-256");
multipartFormContent.Add(new StringContent("comments"), comments);
using var httpClient = CreateHttpClient();
var folders = await httpClient.GetFromJsonAsync<FolderList>(@$"folders?path={destinationPath}");
var folder = folders.Items.SingleOrDefault(x => x.Path.ToLower().Equals(destinationPath.ToLower()));
if (folder != null)
{
await using (var memoryStreamToUpload = new MemoryStream(buffer))
{
multipartFormContent.Add(new StreamContent(memoryStreamToUpload), "file", fileName);
var response = await httpClient.PostAsync($"folders/{folder.Id}/files", multipartFormContent);
await EnsureSuccessAsync(response);
var file = await response.Content.ReadFromJsonAsync<FileItem>();
uploadedFileId = file.Id;
memoryStreamToUpload.Close();
}
}
else
{
throw new FtpException($"Folder {destinationPath} not found on FTP server");
}
}
catch (Exception e)
{
throw new FtpException($"Error in Uploading to the folder {destinationPath} on FTP server. " + e.Message, e);
}
return uploadedFileId;
}
private static async Task EnsureSuccessAsync(HttpResponseMessage httpResponseMessage)
{
if (httpResponseMessage.IsSuccessStatusCode)
{
return;
}
var reasonPhrase = httpResponseMessage.ReasonPhrase;
switch (httpResponseMessage.StatusCode)
{
case HttpStatusCode.UnprocessableEntity:
var unprocessableEntityError = await httpResponseMessage.Content.ReadFromJsonAsync<UnprocessableEntityError>();
var semanticErrors = new StringBuilder();
foreach (var detail in unprocessableEntityError.SemanticErrors.Select(
semanticError => $"Field: {semanticError.Field}, Rejected: {semanticError.Rejected}, Message: {semanticError.Message}"))
{
semanticErrors.AppendLine(detail);
}
throw new HttpRequestException(
"Calling the FTP Service resulting in an error with HttpStatusCode:" +
$" {httpResponseMessage.StatusCode}, ErrorCode:{unprocessableEntityError.ErrorCode} | ErrorDetail: {unprocessableEntityError.Detail} | {semanticErrors}");
default:
var error = await httpResponseMessage.Content.ReadFromJsonAsync<Error>();
throw new HttpRequestException(
$"Calling the FTP Service resulting in an error with unexpected HttpStatusCode: " +
$"{httpResponseMessage.StatusCode}, ErrorCode:{error.ErrorCode} | Detail: {error.Detail} | HttpReason: {reasonPhrase}");
}
}
private static async Task EnsureSignOnSuccessAsync(HttpResponseMessage httpResponseMessage)
{
if (httpResponseMessage.IsSuccessStatusCode)
{
return;
}
var reasonPhrase = httpResponseMessage.ReasonPhrase;
var authErrorContent = await httpResponseMessage.Content.ReadAsStringAsync();
var authError = JsonSerializer.Deserialize<AuthError>(authErrorContent);
throw new HttpRequestException(
$"Calling the FTP Service resulting in an error with HttpStatusCode:" +
$" {httpResponseMessage.StatusCode}, ErrorCode:{authError.Error} | Description: {authError.ErrorDescription} | HttpReason: {reasonPhrase}");
}
private HttpClient CreateHttpClient()
{
HttpClient httpClient = httpClientFactory.CreateClient("FtpAPIClient");
httpClient.BaseAddress = new Uri($@"{FtpConfiguration.Host}/{FtpApiVersionPath}");
httpClient.DefaultRequestHeaders.Add("accept", "application/json");
httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", AccessToken);
return httpClient;
}
private async Task<string> SendFileDownloadRequestAsync(
string nameOfFileToBeDownloaded,
string localFolderPath,
string localFileName,
FileItem file,
HttpClient httpClient,
string downloadFilePath)
{
string downloadedFileId;
if (file != null)
{
httpClient.DefaultRequestHeaders.Clear();
httpClient.DefaultRequestHeaders.Add("accept", "application/octet-stream");
httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", AccessToken);
var downloadResponse = await httpClient.GetAsync($"files/{file.Id}/download");
await EnsureSuccessAsync(downloadResponse);
await using var streamToReadFrom = await downloadResponse.Content.ReadAsStreamAsync();
await using var fs = new FileStream(@$"{localFolderPath}\{localFileName}", FileMode.OpenOrCreate);
await streamToReadFrom.CopyToAsync(fs);
fs.Close();
downloadedFileId = file.Id;
}
else
{
throw new FtpException(
$"File {nameOfFileToBeDownloaded} under folder {downloadFilePath} not found on FTP server");
}
return downloadedFileId;
}
private void Dispose(bool disposing)
{
if (disposing && !disposed)
{
try
{
using var httpClient = CreateHttpClient();
var httpResponse = httpClient.PostAsync($"{AccessToken}/revoke", null);
}
catch (Exception e)
{
// see where can we log error
}
disposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
}
/////////////////////////////FtpConfiguration
using System;
namespace FtpUtilityLib
{
public sealed class FtpConfiguration
{
private int maxNumberOfSignOnAttempts;
private int waitTimeBeforeNextAttemptInMilliseconds;
public FtpConfiguration(string host, string username, string password)
{
WaitTimeBeforeNextAttemptInMilliseconds = 30000;
MaxNumberOfSignOnAttempts = 3;
Host = host;
Username = username;
Password = password;
}
public FtpConfiguration(
string host,
string username,
string password,
int waitTimeBeforeNextAttemptInMilliseconds,
int maxNumberOfSignOnAttempts)
{
WaitTimeBeforeNextAttemptInMilliseconds = waitTimeBeforeNextAttemptInMilliseconds;
MaxNumberOfSignOnAttempts = maxNumberOfSignOnAttempts;
Host = host;
Username = username;
Password = password;
}
public string Username { get; }
public string Password { get; }
public string Host { get; }
public int MaxNumberOfSignOnAttempts
{
get => maxNumberOfSignOnAttempts;
private set
{
if (value < 1 || value > 6)
throw new ArgumentOutOfRangeException(
$"MaxNumberOfSignOnAttempts- Allowed range of value is between 1 and 6. You have provided {value}");
maxNumberOfSignOnAttempts = value;
}
}
public int WaitTimeBeforeNextAttemptInMilliseconds
{
get => waitTimeBeforeNextAttemptInMilliseconds;
private set
{
if (value < 1000 || value > 60000)
throw new ArgumentOutOfRangeException(
$"WaitTimeBeforeNextAttemptInMilliseconds- Allowed range of value is between 1000 and 60000. You have provided {value}");
waitTimeBeforeNextAttemptInMilliseconds = value;
}
}
}
}
/////////////////HttpClientFactory
using System.Net.Http;
namespace FtpUtilityLib
{
internal sealed class HttpClientFactory : IHttpClientFactory
{
public HttpClient CreateClient(string name)
{
return new HttpClient();
}
}
}发布于 2021-06-30 21:20:50
下面是一个自动化单元测试的Test类。增加了两部分,因为文字的限制,我可以张贴。,这是第1部分。您可以使用编译错误调整引用。TesTResponses类在第2部分上载中
///Create a TestFiles folder under MSTestProject and then create SampleFile.json file in that folder. Go to properties of file select copyAlways for CopyToOutputDirectory
using FtpUtilityLib.Models;
using System.Collections.Generic;
namespace MoveItRestApiUtilityLib.Tests
{
//////////////////////FakeHttpMessageHandler
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
public class FakeHttpMessageHandler : DelegatingHandler
{
public Dictionary<(string, string), HttpResponseMessage> DesiredHttpResponseMessagesByUriAbsolutePath { get; }
public FakeHttpMessageHandler()
{
DesiredHttpResponseMessagesByUriAbsolutePath = new Dictionary<(string, string), HttpResponseMessage>();
//PopulateDesiredResponseList();
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
if (request.RequestUri.Query.Contains("perpage=100&page="))
{
return new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FilesResponse), Encoding.UTF8,
"application/json")
};
}
var requestUriAbsolutePath = request.RequestUri.AbsolutePath;
var responseMessage = DesiredHttpResponseMessagesByUriAbsolutePath[(requestUriAbsolutePath, request.Method.Method.ToLower())];
return await Task.FromResult(responseMessage);
}
}
/////////////////////////////
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
public static class AssertEx
{
public static void AssertExceptionMessageContains(IEnumerable<string> expected, string actual)
{
var messages = new List<string>();
foreach (var item in expected)
{
if (actual.IndexOf(item, StringComparison.OrdinalIgnoreCase) < 0)
{
messages.Add("Expected to find the substring: \"" + item + "\", in the Exception Message: " + actual);
}
}
if (messages.Any())
{
throw new AssertFailedException(String.Join(",", messages));
}
}
}
//////////////////////////////Partial Test Class in a Test file
[ExcludeFromCodeCoverage]
[TestClass]
public partial class FtpApiServiceGatewayTests
{
public static string HostName => "https://ATestHost.com";
//private Mock httpClientFactoryMock = new Mock<IHttpClientFactory>();
FtpConfiguration ftpConfiguration =
new FtpConfiguration(HostName, "SomeUser", "SomePassword");
[TestMethod]
public async Task SignOnToHost_WhenValidUserIdAndPassword_ShouldSuccess()
{
//ARRANGE
var httpClientFactoryMock = new Mock<IHttpClientFactory>();
var fakeHttpMessageHandler = new FakeHttpMessageHandler();
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/token", "post"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.TokenResponse), Encoding.UTF8,
"application/json")
});
var fakeHttpClient = new HttpClient(fakeHttpMessageHandler);
httpClientFactoryMock.Setup(h => h.CreateClient(It.IsAny<string>())).Returns(fakeHttpClient);
var ftpApiServiceGateway = new FtpApiServiceGateway(ftpConfiguration, httpClientFactoryMock.Object);
//ACT
await ftpApiServiceGateway.SignOnToHostAsync();
//ASSERT
Assert.AreEqual(TestResponse.TokenResponse.AccessToken, ftpApiServiceGateway.AccessToken);
}
[TestMethod]
public async Task SignOnToHost_WhenInvalidUserIdOrPassword_ShouldThrowException()
{
//ARRANGE
var r = JsonSerializer.Serialize(TestResponse.TokenErrorResponse);
var httpClientFactoryMock = new Mock<IHttpClientFactory>();
var fakeHttpMessageHandler = new FakeHttpMessageHandler();
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/token", "post"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.BadRequest,
Content = new StringContent(
JsonSerializer.Serialize(
TestResponse.TokenErrorResponse),
Encoding.UTF8,
"application/json")
});
var fakeHttpClient = new HttpClient(fakeHttpMessageHandler);
httpClientFactoryMock.Setup(h => h.CreateClient(It.IsAny<string>())).Returns(fakeHttpClient);
var ftpApiServiceGateway = new FtpApiServiceGateway(ftpConfiguration, httpClientFactoryMock.Object);
//ACT
try
{
await ftpApiServiceGateway.SignOnToHostAsync();
Assert.Fail("Expected Exception of type: FtpException during this test, but it was not thrown");
}
catch (FtpException e)
{
//ASSERT
AssertEx.AssertExceptionMessageContains(new string[]
{
"Error in logging to FTP server",
HostName,
TestResponse.TokenErrorResponse.ErrorDescription,
TestResponse.TokenErrorResponse.Error,
"Calling the FTP Service resulting in an error with HttpStatusCode:"
},
e.Message);
}
}
[TestMethod]
public async Task DownloadFileAsync_ByFilesAPI_WhenValidFile_ShouldSuccess()
{
//ARRANGE
var nameOfFileToBeDownloaded = "SampleFile.json";
var localFolderPath = @".\TestFiles";
var localFileName = "ATest2.json";
var httpClientFactoryMock = new Mock<IHttpClientFactory>();
var fakeHttpMessageHandler = new FakeHttpMessageHandler();
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/files", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FilesResponse), Encoding.UTF8,
"application/json")
});
var filePathName = @".\TestFiles\SampleFile.json";
using var fileStream = File.OpenRead(filePathName);
var ms = new MemoryStream();
fileStream.CopyTo(ms);
var content = new ByteArrayContent(ms.GetBuffer());
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "SampleFile.json"
};
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/files/769379085/download", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
ReasonPhrase = "OK",
Content = content
});
var fakeHttpClient = new HttpClient(fakeHttpMessageHandler);
httpClientFactoryMock.Setup(h => h.CreateClient(It.IsAny<string>())).Returns(fakeHttpClient);
var ftpApiServiceGateway = new FtpApiServiceGateway(ftpConfiguration, httpClientFactoryMock.Object);
//ACT
var fileId = await ftpApiServiceGateway.DownloadFileAsync(
nameOfFileToBeDownloaded,
localFolderPath, localFileName);
//ASSERT
Assert.IsFalse(string.IsNullOrEmpty(fileId));
}
[TestMethod]
public async Task DownloadFileAsync_WhenValidFile_ShouldSuccess()
{
//ARRANGE
var nameOfFileToBeDownloaded = "SampleFile.json";
var downloadFilePath = TestResponse.FtpServerTestFolderPath;
var localFolderPath = @".\TestFiles";
var localFileName = "ATest2.json";
var httpClientFactoryMock = new Mock<IHttpClientFactory>();
var fakeHttpMessageHandler = new FakeHttpMessageHandler();
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FoldersResponse), Encoding.UTF8,
"application/json")
});
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders/715431145/files", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FilesResponse), Encoding.UTF8,
"application/json")
});
var filePathName = @".\TestFiles\SampleFile.json";
using var fileStream = File.OpenRead(filePathName);
var ms = new MemoryStream();
fileStream.CopyTo(ms);
var content = new ByteArrayContent(ms.GetBuffer());
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "SampleFile.json"
};
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/files/769379085/download", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
ReasonPhrase = "OK",
Content = content
});
var fakeHttpClient = new HttpClient(fakeHttpMessageHandler);
httpClientFactoryMock.Setup(h => h.CreateClient(It.IsAny<string>())).Returns(fakeHttpClient);
var ftpApiServiceGateway = new FtpApiServiceGateway(ftpConfiguration, httpClientFactoryMock.Object);
//ACT
var fileId = await ftpApiServiceGateway.DownloadFileAsync(
nameOfFileToBeDownloaded,
downloadFilePath,
localFolderPath, localFileName);
//ASSERT
Assert.IsFalse(string.IsNullOrEmpty(fileId));
}
[TestMethod]
public async Task DownloadFileAsync_WhenInvalidSourceFolder_ThrowsException()
{
//ARRANGE
var nameOfFileToBeDownloaded = "SampleFile.json";
var downloadFilePath = @"/Data/InvalidFolder";
var localFolderPath = @".\TestFiles";
var localFileName = "ATest2.json";
var httpClientFactoryMock = new Mock<IHttpClientFactory>();
var fakeHttpMessageHandler = new FakeHttpMessageHandler();
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FolderNotFoundResponse), Encoding.UTF8,
"application/json")
});
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders/715431145/files", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FilesResponse), Encoding.UTF8,
"application/json")
});
var filePathName = @".\TestFiles\SampleFile.json";
using var fileStream = File.OpenRead(filePathName);
var ms = new MemoryStream();
fileStream.CopyTo(ms);
var content = new ByteArrayContent(ms.GetBuffer());
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = nameOfFileToBeDownloaded
};
var fakeHttpClient = new HttpClient(fakeHttpMessageHandler);
httpClientFactoryMock.Setup(h => h.CreateClient(It.IsAny<string>())).Returns(fakeHttpClient);
var ftpApiServiceGateway = new FtpApiServiceGateway(ftpConfiguration, httpClientFactoryMock.Object);
try
{
//ACT
var fileId = await ftpApiServiceGateway.DownloadFileAsync(
nameOfFileToBeDownloaded,
downloadFilePath,
localFolderPath, localFileName);
//ASSERT
Assert.Fail("Expected Exception of type: FtpException during this test, but it was not thrown");
}
catch (FtpException e)
{
//Assert
AssertEx.AssertExceptionMessageContains(new string[]
{
$"Folder {downloadFilePath} not found on FTP server"
},
e.Message);
}
}
[TestMethod]
public async Task DownloadFileAsync_WhenInvalidSourceFilename_ThrowsException()
{
//ARRANGE
var nameOfFileToBeDownloaded = "InvalidFile.json";
var downloadFilePath = TestResponse.FtpServerTestFolderPath;
var localFolderPath = @"C:\TestFolder\Test";
var localFileName = "ATest2.json";
var httpClientFactoryMock = new Mock<IHttpClientFactory>();
var fakeHttpMessageHandler = new FakeHttpMessageHandler();
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FoldersResponse), Encoding.UTF8,
"application/json")
});
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders/715431145/files", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FilesResponse), Encoding.UTF8,
"application/json")
});
var fakeHttpClient = new HttpClient(fakeHttpMessageHandler);
httpClientFactoryMock.Setup(h => h.CreateClient(It.IsAny<string>())).Returns(fakeHttpClient);
var ftpApiServiceGateway = new FtpApiServiceGateway(ftpConfiguration, httpClientFactoryMock.Object);
try
{
//ACT
var fileId = await ftpApiServiceGateway.DownloadFileAsync(
nameOfFileToBeDownloaded,
downloadFilePath,
localFolderPath, localFileName);
//ASSERT
Assert.Fail("Expected Exception of type: FtpException during this test, but it was not thrown");
}
catch (FtpException e)
{
//Assert
AssertEx.AssertExceptionMessageContains(new string[]
{
$"File {nameOfFileToBeDownloaded} under folder {downloadFilePath} not found on FTP server"
},
e.Message);
}
}
[TestMethod]
public async Task DownloadFileAsync_WhenAccessDenied_ThrowsException()
{
//ARRANGE
var nameOfFileToBeDownloaded = "InvalidFile.json";
var downloadFilePath = TestResponse.FtpServerTestFolderPath;
var localFolderPath = @"C:\TestFolder\Test";
var localFileName = "ATest2.json";
var httpClientFactoryMock = new Mock<IHttpClientFactory>();
var fakeHttpMessageHandler = new FakeHttpMessageHandler();
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.Forbidden,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.ErrorResponse), Encoding.UTF8,
"application/json")
});
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders/715431145/files", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FilesResponse), Encoding.UTF8,
"application/json")
});
var fakeHttpClient = new HttpClient(fakeHttpMessageHandler);
httpClientFactoryMock.Setup(h => h.CreateClient(It.IsAny<string>())).Returns(fakeHttpClient);
var ftpApiServiceGateway = new FtpApiServiceGateway(ftpConfiguration, httpClientFactoryMock.Object);
try
{
//ACT
var fileId = await ftpApiServiceGateway.DownloadFileAsync(
nameOfFileToBeDownloaded,
downloadFilePath,
localFolderPath, localFileName);
//ASSERT
Assert.Fail("Expected Exception of type: FtpException during this test, but it was not thrown");
}
catch (FtpException e)
{
//Assert
AssertEx.AssertExceptionMessageContains(new string[]
{
"Error in downloading the file",
nameOfFileToBeDownloaded,
"from FTP server"
},
e.Message);
}
}
[TestMethod]
public async Task DownloadFileAsync_WhenInternalServerError_ThrowsException()
{
//ARRANGE
var nameOfFileToBeDownloaded = "SampleFile.json";
var downloadFilePath = TestResponse.FtpServerTestFolderPath;
var localFolderPath = @"C:TestFTP\Download";
var localFileName = "ATest2.json";
var httpClientFactoryMock = new Mock<IHttpClientFactory>();
var fakeHttpMessageHandler = new FakeHttpMessageHandler();
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.InternalServerError,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.ErrorResponse), Encoding.UTF8,
"application/json")
});
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders/715431145/files", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FilesResponse), Encoding.UTF8,
"application/json")
});
// var dir = Directory.GetCurrentDirectory();
var filePathName = @".\TestFiles\SampleFile.json";
using var fileStream = File.OpenRead(filePathName);
var ms = new MemoryStream();
fileStream.CopyTo(ms);
var content = new ByteArrayContent(ms.GetBuffer());
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = nameOfFileToBeDownloaded
};
var fakeHttpClient = new HttpClient(fakeHttpMessageHandler);
httpClientFactoryMock.Setup(h => h.CreateClient(It.IsAny<string>())).Returns(fakeHttpClient);
var ftpApiServiceGateway = new FtpApiServiceGateway(ftpConfiguration, httpClientFactoryMock.Object);
try
{
//ACT
var fileId = await ftpApiServiceGateway.DownloadFileAsync(
nameOfFileToBeDownloaded,
downloadFilePath,
localFolderPath, localFileName);
//ASSERT
Assert.Fail("Expected Exception of type: FtpException during this test, but it was not thrown");
}
catch (FtpException e)
{
//Assert
AssertEx.AssertExceptionMessageContains(new string[]
{
"Error in downloading the file",
nameOfFileToBeDownloaded,
"from FTP server"
},
e.Message);
}
}
}发布于 2021-06-30 21:33:28
这是自动化测试的第2部分。
///////////////TestResponses class
public static class TestResponse
{
public static Token TokenResponse = new Token()
{
AccessToken = "TestTokenMwzVguxPqzF6WpIXSDfIinPr2ZgX3zBcCYo-qguVYMHSQxmwNEsdVEblVQdWAxUHriBcPaVIwZMxeNy6b5fPD_cZdtgNMiDjdKClRCM9Ps8yg",
ExpiresIn = 1199,
RefreshToken = "TestRefreshToken57Bne4Cs8lSXx4OYbwjsAYaJBS4uNpAN_mIrawiyC1KmGBc6YCIxe7nEQXhcCPHN3mi8nby3JkIPX190g1Ducjm5hxRHBGOmjMbDeZ35mEjvbUSFbXHrl7xzWPidkcvAg2bomkKDpwojoKxW1RkfR2UG_Qb_o7hrYS4JdQOUm3_uQcvvW9q5uR3snOEiM3Ge7U39HUBOSqOhQ",
TokenType = "Bearer"
};
public static string FtpServerTestFolderPath = @"/Data/CSS_IntTest";
public static FolderList FoldersResponse =>
new FolderList()
{
Items = new List<FolderItem>()
{
new FolderItem()
{
FolderType = "Normal",
Id = "715431145",
IsShared = true,
LastContentChangeTime = "2021-05-27T09:58:16",
Name = "CSS_IntTest",
ParentId = "510768038",
Path = FtpServerTestFolderPath
},
new FolderItem()
{
FolderType = "Normal",
Id = "71556789",
IsShared = true,
LastContentChangeTime = "2020-05-29T09:58:16",
Name = "CSS_IntTest2",
ParentId = "510768038",
Path = @"/Data/CSS_IntTest2"
}
},
Paging = new Paging()
{
Page = 1,
PerPage = 25,
TotalItems = 1,
TotalPages = 1
},
Sorting = new List<Sorting>()
{
new Sorting()
{
SortDirection = "asc",
SortField = "Path",
}
}
};
public static FolderList FolderNotFoundResponse =>
new FolderList()
{
Items = new List<FolderItem>(),
Paging = new Paging()
{
Page = 1,
PerPage = 25,
TotalItems = 0,
TotalPages = 1
},
Sorting = new List<Sorting>()
{
new Sorting()
{
SortDirection = "asc",
SortField = "Path",
}
}
};
public static FileList FilesResponse =>
new FileList()
{
Items = new List<FileItem>()
{
new FileItem()
{
CurrentFileType = null,
DownloadCount = 0,
FolderID = null,
Hash = null,
Id = "769379085",
Name = "samplefile.json" ,
//OrgId = null ,
OriginalFileType = null,
OriginalFilename =null,
Path = @$"{FtpServerTestFolderPath}\samplefile.json",
Size = 35935783,
UploadAgentBrand = null,
UploadAgentVersion = null,
UploadComment = null,
UploadIP = null,
UploadIntegrity= 0 ,
UploadStamp ="2021-05-21T16:45:13" ,
UploadUserFullName = null,
//UploadUserRealname = null,
UploadUsername = null
},
new FileItem()
{
CurrentFileType = null,
DownloadCount = 0,
FolderID = null,
Hash = null,
Id = "769379088",
Name = "TestAssociate.json" ,
//OrgId = null ,
OriginalFileType = null,
OriginalFilename =null,
Path = @$"{FtpServerTestFolderPath}/TestAssociate.json",
Size = 541,
UploadAgentBrand = null,
UploadAgentVersion = null,
UploadComment = null,
UploadIP = null,
UploadIntegrity= 0 ,
UploadStamp ="2021-05-27T09:58:16 " ,
UploadUserFullName = null,
//UploadUserRealname = null,
UploadUsername = null
}
},
Paging = new Paging()
{
Page = 1,
PerPage = 100,
TotalItems = 2,
TotalPages = 1
},
Sorting = new List<Sorting>()
{
new Sorting()
{
SortDirection = "asc",
SortField = "Name",
}
}
};
public static FileItem FileResponse =>
new FileItem()
{
CurrentFileType = null,
DownloadCount = 0,
FolderID = null,
Hash = null,
Id = "769379088",
Name = "samplefile.json",
//OrgId = null,
OriginalFileType = null,
OriginalFilename = null,
Path = @$"{FtpServerTestFolderPath }/samplefile.json",
Size = 541,
UploadAgentBrand = null,
UploadAgentVersion = null,
UploadComment = null,
UploadIP = null,
UploadIntegrity = 0,
UploadStamp = "2021-05-27T09:58:16 ",
UploadUserFullName = null,
// UploadUserRealname = null,
UploadUsername = null
};
public static FolderItem FolderResponse =>
new FolderItem()
{
FolderType = "Normal",
Id = "715431145",
IsShared = true,
LastContentChangeTime = "2021-05-27T09:58:16",
Name = "CSS_IntTest",
ParentId = "510768038",
Path = FtpServerTestFolderPath
};
public static AuthError TokenErrorResponse =>
new AuthError()
{
Error = "This is a Test error",
ErrorDescription = "This is a Test error Description"
};
public static Error ErrorResponse =>
new Error()
{
Detail = "This is a test error detail",
ErrorCode = 4567,
Title = "This a test error title"
};
public static UnprocessableEntityError UnprocessableEntityResponse =>
new UnprocessableEntityError()
{
SemanticErrors = new List<SemanticError>()
{
new SemanticError()
{
Field = "fileName",
Message = "Invalid character in fileName",
Rejected = "Yes"
},
new SemanticError()
{
Field = "Header",
Message = "Invalid Value",
Rejected = "Yes"
}
},
Detail = "This is a test UnprocessableEntityError detail",
ErrorCode = 1234,
Title = "This a test error title"
};
}
/////////////////////////// Another test file
public partial class FtpApiServiceGatewayTests
{
[TestMethod]
public async Task UploadFileFromBufferAsync_WhenValidFile_ShouldSuccess()
{
//ARRANGE
var fileName = "samplefile.json";
var destinationFolder = TestResponse.FtpServerTestFolderPath;
var sourceFolder = @".\TestFiles";
await using var fileStream = File.Open($"{sourceFolder}/{fileName}", FileMode.Open);
// Be sure it's positioned to the beginning of the stream.
fileStream.Position = 0;
var memoryStream = new MemoryStream();
fileStream.CopyTo(memoryStream);
var content = memoryStream.GetBuffer();
var httpClientFactoryMock = new Mock<IHttpClientFactory>();
var fakeHttpMessageHandler = new FakeHttpMessageHandler();
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FoldersResponse), Encoding.UTF8,
"application/json")
});
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders/715431145/files", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FilesResponse), Encoding.UTF8,
"application/json")
});
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders/715431145/files", "post"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.Created,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FileResponse), Encoding.UTF8,
"application/json")
});
var fakeHttpClient = new HttpClient(fakeHttpMessageHandler);
httpClientFactoryMock.Setup(h => h.CreateClient(It.IsAny<string>())).Returns(fakeHttpClient);
var ftpApiServiceGateway = new FtpApiServiceGateway(ftpConfiguration, httpClientFactoryMock.Object);
//ACT
var fileId = await ftpApiServiceGateway.UploadFileFromBufferAsync(
content,
destinationFolder,
"ATest2.json", "This is a test comment");
//ASSERT
Assert.IsFalse(string.IsNullOrEmpty(fileId));
}
[TestMethod]
public async Task UploadFileFromBufferAsync_WhenInvalidDestination_ShouldSuccess()
{
//ARRANGE
var fileName = "samplefile.json";
var destinationFolder = TestResponse.FtpServerTestFolderPath + "/InValidFolder";
var sourceFolder = @".\TestFiles";
await using var fileStream = File.Open($"{sourceFolder}/{fileName}", FileMode.Open);
// Be sure it's positioned to the beginning of the stream.
fileStream.Position = 0;
var memoryStream = new MemoryStream();
fileStream.CopyTo(memoryStream);
var content = memoryStream.GetBuffer();
var httpClientFactoryMock = new Mock<IHttpClientFactory>();
var fakeHttpMessageHandler = new FakeHttpMessageHandler(); fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FolderNotFoundResponse), Encoding.UTF8,
"application/json")
}); fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders/715431145/files", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FilesResponse), Encoding.UTF8,
"application/json")
});
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders/715431145/files", "post"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.Created,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FileResponse), Encoding.UTF8,
"application/json")
});
var fakeHttpClient = new HttpClient(fakeHttpMessageHandler);
httpClientFactoryMock.Setup(h => h.CreateClient(It.IsAny<string>())).Returns(fakeHttpClient);
var ftpApiServiceGateway = new FtpApiServiceGateway(ftpConfiguration, httpClientFactoryMock.Object);
try
{
var fileId = await ftpApiServiceGateway.UploadFileFromBufferAsync(
content,
destinationFolder,
"ATest2.json", "This is a test comment");
//ASSERT
Assert.Fail("Expected Exception of type: FtpException during this test, but it was not thrown");
}
catch (FtpException e)
{
//Assert
AssertEx.AssertExceptionMessageContains(new string[]
{
$"Folder {destinationFolder} not found on FTP server",
"Error in Uploading to the folder",
"To the folder",
destinationFolder,
"on FTP server"
},
e.Message);
}
}
[TestMethod]
public async Task UploadFileFromBufferAsync_WhenInternalServerError_ShouldSuccess()
{
//ARRANGE
var fileName = "samplefile.json";
var destinationFolder = TestResponse.FtpServerTestFolderPath;
var sourceFolder = @".\TestFiles";
await using var fileStream = File.Open($"{sourceFolder}/{fileName}", FileMode.Open);
// Be sure it's positioned to the beginning of the stream.
fileStream.Position = 0;
var memoryStream = new MemoryStream();
fileStream.CopyTo(memoryStream);
var content = memoryStream.GetBuffer();
var httpClientFactoryMock = new Mock<IHttpClientFactory>();
var fakeHttpMessageHandler = new FakeHttpMessageHandler();
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FoldersResponse), Encoding.UTF8,
"application/json")
});
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders/715431145/files", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FilesResponse), Encoding.UTF8,
"application/json")
});
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders/715431145/files", "post"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.InternalServerError,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.ErrorResponse), Encoding.UTF8,
"application/json")
});
var fakeHttpClient = new HttpClient(fakeHttpMessageHandler);
httpClientFactoryMock.Setup(h => h.CreateClient(It.IsAny<string>())).Returns(fakeHttpClient);
var ftpApiServiceGateway = new FtpApiServiceGateway(ftpConfiguration, httpClientFactoryMock.Object);
//ACT
try
{
var fileId = await ftpApiServiceGateway.UploadFileFromBufferAsync(
content,
destinationFolder,
"ATest2.json", "This is a test comment");
Assert.Fail("Expected Exception of type: FtpException during this test, but it was not thrown");
}
catch (FtpException e)
{
AssertEx.AssertExceptionMessageContains(new string[]
{
$"Calling the FTP Service resulting in an error with unexpected HttpStatusCode:",
HttpStatusCode.InternalServerError.ToString(),
TestResponse.ErrorResponse.Detail,
TestResponse.ErrorResponse.ErrorCode.ToString(),
"Error in Uploading to the folder",
"To the folder",
destinationFolder,
"on FTP server"
},
e.Message);
}
}
[TestMethod]
public async Task UploadFileAsync_WhenValidFile_ShouldSuccess()
{
//ARRANGE
var destinationPath = TestResponse.FtpServerTestFolderPath;
var sourceFilePathName = @".\TestFiles\samplefile.json";
var httpClientFactoryMock = new Mock<IHttpClientFactory>();
var fakeHttpMessageHandler = new FakeHttpMessageHandler();
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FoldersResponse), Encoding.UTF8,
"application/json")
});
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders/715431145/files", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FilesResponse), Encoding.UTF8,
"application/json")
});
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders/715431145/files", "post"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.Created,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FileResponse), Encoding.UTF8,
"application/json")
});
var fakeHttpClient = new HttpClient(fakeHttpMessageHandler);
httpClientFactoryMock.Setup(h => h.CreateClient(It.IsAny<string>())).Returns(fakeHttpClient);
var ftpApiServiceGateway = new FtpApiServiceGateway(ftpConfiguration, httpClientFactoryMock.Object);
//ACT
var fileId = await ftpApiServiceGateway.UploadFile(
sourceFilePathName,
destinationPath);
Assert.IsFalse(string.IsNullOrEmpty(fileId));
}
[TestMethod]
public async Task UploadFileAsync_WhenInValidDestinationFolder_ThrowsException()
{
//ARRANGE
var destinationPath = TestResponse.FtpServerTestFolderPath + "/InValidFolder";
var sourceFilePathName = @".\TestFiles\samplefile.json";
var httpClientFactoryMock = new Mock<IHttpClientFactory>();
var fakeHttpMessageHandler = new FakeHttpMessageHandler();
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FoldersResponse), Encoding.UTF8,
"application/json")
});
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders/715431145/files", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FilesResponse), Encoding.UTF8,
"application/json")
});
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders/715431145/files", "post"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.Created,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FileResponse), Encoding.UTF8,
"application/json")
});
var fakeHttpClient = new HttpClient(fakeHttpMessageHandler);
httpClientFactoryMock.Setup(h => h.CreateClient(It.IsAny<string>())).Returns(fakeHttpClient);
var ftpApiServiceGateway = new FtpApiServiceGateway(ftpConfiguration, httpClientFactoryMock.Object);
//ACT
try
{
var fileId = await ftpApiServiceGateway.UploadFile(
sourceFilePathName,
destinationPath);
Assert.Fail("Expected Exception of type: FtpException during this test, but it was not thrown");
}
catch (FtpException e)
{
//Assert
AssertEx.AssertExceptionMessageContains(new string[]
{
$"Folder {destinationPath} not found on FTP server",
"Error in Uploading the file",
sourceFilePathName,
"To the folder",
destinationPath,
"on FTP server"
},
e.Message);
}
}
[TestMethod]
public async Task UploadFileAsync_WhenFailedWithHttp422_ThrowsException()
{
//ARRANGE
var destinationPath = TestResponse.FtpServerTestFolderPath;
var sourceFilePathName = @".\TestFiles\samplefile.json";
var httpClientFactoryMock = new Mock<IHttpClientFactory>();
var fakeHttpMessageHandler = new FakeHttpMessageHandler();
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FoldersResponse), Encoding.UTF8,
"application/json")
});
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders/715431145/files", "get"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.FilesResponse), Encoding.UTF8,
"application/json")
});
fakeHttpMessageHandler.DesiredHttpResponseMessagesByUriAbsolutePath.Add(
("/api/v1/folders/715431145/files", "post"),
new HttpResponseMessage()
{
StatusCode = HttpStatusCode.UnprocessableEntity,
Content = new StringContent(JsonSerializer.Serialize(TestResponse.UnprocessableEntityResponse), Encoding.UTF8,
"application/json")
});
var fakeHttpClient = new HttpClient(fakeHttpMessageHandler);
httpClientFactoryMock.Setup(h => h.CreateClient(It.IsAny<string>())).Returns(fakeHttpClient);
var ftpApiServiceGateway = new FtpApiServiceGateway(ftpConfiguration, httpClientFactoryMock.Object);
//ACT
try
{
var fileId = await ftpApiServiceGateway.UploadFile(
sourceFilePathName,
destinationPath);
Assert.Fail("Expected Exception of type: FtpException during this test, but it was not thrown");
}
catch (FtpException e)
{
//Assert
AssertEx.AssertExceptionMessageContains(new string[]
{
$"Calling the FTP Service resulting in an error with HttpStatusCode",
HttpStatusCode.UnprocessableEntity.ToString(),
TestResponse.UnprocessableEntityResponse.ErrorCode.ToString(),
TestResponse.UnprocessableEntityResponse.Detail,
TestResponse.UnprocessableEntityResponse.SemanticErrors[0].Message,
TestResponse.UnprocessableEntityResponse.SemanticErrors[1].Message,
$"Error in Uploading the file",
destinationPath,
"on FTP server"
},
e.Message);
}
}
}
}https://stackoverflow.com/questions/68187479
复制相似问题