首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >我们如何通过C# .net核心来使用MoveIt RestFul应用程序接口

我们如何通过C# .net核心来使用MoveIt RestFul应用程序接口
EN

Stack Overflow用户
提问于 2021-06-30 09:32:46
回答 3查看 101关注 0票数 -2

我正在研究MoveIt应用程序接口以及如何使用C#代码来使用它。尝试查找一些基于https://docs.ipswitch.com/MOVEit/Transfer2020/API/rest/#operation/POSTapi%2Fv1%2Ffolders%2F%7BId%7D%2Fsubfolders-1.0https://docs.ipswitch.com/MOVEit/Transfer2019_1/API/Rest/的示例代码MoveIt也有一个“REST API Swagger用户界面”

另外,我想使用.NET内核。我环顾四周,没有找到很多东西,最终开始构建一个,现在我已经分享了它。

EN

回答 3

Stack Overflow用户

发布于 2021-06-30 09:32:46

我做了大量的研究和试验,最终我能够写出一个可测试的代码,我认为我可以分享。这是一些示例代码,我将模型类放在这里,这些模型类基于https://docs.ipswitch.com/MOVEit/Transfer2019_1/API/Rest/和MoveIt的REST API Swagger用户界面,它使用HttpClient和HtttpClient工厂。还在两个部分中添加了自动化单元测试的代码。

代码语言:javascript
运行
复制
//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();
        }
    }
}
票数 1
EN

Stack Overflow用户

发布于 2021-06-30 21:20:50

下面是一个自动化单元测试的Test类。增加了两部分,因为文字的限制,我可以张贴。,这是第1部分。您可以使用编译错误调整引用。TesTResponses类在第2部分上载中

代码语言:javascript
运行
复制
///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);
            }
        }
    }
票数 1
EN

Stack Overflow用户

发布于 2021-06-30 21:33:28

这是自动化测试的第2部分。

代码语言:javascript
运行
复制
///////////////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);
            }

        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68187479

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档