|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#nullable disable
using System.Net;
using System.Net.Http;
using Moq;
namespace Microsoft.NET.Sdk.Publish.Tasks.ZipDeploy.Tests
{
public class ZipDeployerTaskTests
{
private static string _testZippedPublishContentsPath;
private static string TestAssemblyToTestZipPath = Path.Combine("Resources", "TestPublishContents.zip");
private static string UserAgentName = "websdk";
private static string UserAgentVersion = "1.0";
public static string TestZippedPublishContentsPath
{
get
{
if (_testZippedPublishContentsPath == null)
{
string codebase = typeof(ZipDeployerTaskTests).Assembly.Location;
string assemblyPath = new Uri(codebase, UriKind.Absolute).LocalPath;
string baseDirectory = Path.GetDirectoryName(assemblyPath);
_testZippedPublishContentsPath = Path.Combine(baseDirectory, TestAssemblyToTestZipPath);
}
return _testZippedPublishContentsPath;
}
}
[Fact]
public async Task ExecuteZipDeploy_InvalidZipFilePath()
{
Mock<IHttpClient> client = new();
ZipDeploy zipDeployer = new();
bool result = await zipDeployer.ZipDeployAsync(string.Empty, "username", "password", "publishUrl", null, "Foo", client.Object, false);
client.Verify(c => c.PostAsync(It.IsAny<Uri>(), It.IsAny<StreamContent>()), Times.Never);
Assert.False(result);
}
/// <summary>
/// ZipDeploy should use PublishUrl if not null or empty, else use SiteName.
/// </summary>
[Theory]
[InlineData("https://sitename.scm.azurewebsites.net", null, "https://sitename.scm.azurewebsites.net/api/zipdeploy?isAsync=true")]
[InlineData("https://sitename.scm.azurewebsites.net", "", "https://sitename.scm.azurewebsites.net/api/zipdeploy?isAsync=true")]
[InlineData("https://sitename.scm.azurewebsites.net", "shouldNotBeUsed", "https://sitename.scm.azurewebsites.net/api/zipdeploy?isAsync=true")]
[InlineData(null, "sitename", "https://sitename.scm.azurewebsites.net/api/zipdeploy?isAsync=true")]
[InlineData("", "sitename", "https://sitename.scm.azurewebsites.net/api/zipdeploy?isAsync=true")]
public async Task ExecuteZipDeploy_PublishUrlOrSiteNameGiven(string publishUrl, string siteName, string expectedZipDeployEndpoint)
{
Action<Mock<IHttpClient>, bool> verifyStep = (client, result) =>
{
client.Verify(c => c.PostAsync(
It.Is<Uri>(uri => string.Equals(uri.AbsoluteUri, expectedZipDeployEndpoint, StringComparison.Ordinal)),
It.Is<StreamContent>(streamContent => IsStreamContentEqualToFileContent(streamContent, TestZippedPublishContentsPath))),
Times.Once);
Assert.Equal($"{UserAgentName}/{UserAgentVersion}", client.Object.DefaultRequestHeaders.GetValues("User-Agent").FirstOrDefault());
Assert.True(result);
};
await RunZipDeployAsyncTest(publishUrl, siteName, UserAgentVersion, HttpStatusCode.OK, verifyStep);
}
[Theory]
[InlineData(null, null)]
[InlineData("", "")]
[InlineData("", null)]
[InlineData(null, "")]
public async Task ExecuteZipDeploy_NeitherPublishUrlNorSiteNameGiven(string publishUrl, string siteName)
{
Action<Mock<IHttpClient>, bool> verifyStep = (client, result) =>
{
client.Verify(c => c.PostAsync(
It.IsAny<Uri>(),
It.IsAny<StreamContent>()),
Times.Never);
Assert.False(client.Object.DefaultRequestHeaders.TryGetValues("User-Agent", out _));
Assert.False(result);
};
await RunZipDeployAsyncTest(publishUrl, siteName, UserAgentVersion, HttpStatusCode.OK, verifyStep);
}
[Theory]
[InlineData(HttpStatusCode.OK, true)]
[InlineData(HttpStatusCode.Accepted, true)]
[InlineData(HttpStatusCode.Forbidden, false)]
[InlineData(HttpStatusCode.NotFound, false)]
[InlineData(HttpStatusCode.RequestTimeout, false)]
[InlineData(HttpStatusCode.InternalServerError, false)]
public async Task ExecuteZipDeploy_VaryingHttpResponseStatuses(HttpStatusCode responseStatusCode, bool expectedResult)
{
Action<Mock<IHttpClient>, bool> verifyStep = (client, result) =>
{
client.Verify(c => c.PostAsync(
It.Is<Uri>(uri => string.Equals(uri.AbsoluteUri, "https://sitename.scm.azurewebsites.net/api/zipdeploy?isAsync=true", StringComparison.Ordinal)),
It.Is<StreamContent>(streamContent => IsStreamContentEqualToFileContent(streamContent, TestZippedPublishContentsPath))),
Times.Once);
Assert.Equal($"{UserAgentName}/{UserAgentVersion}", client.Object.DefaultRequestHeaders.GetValues("User-Agent").FirstOrDefault());
Assert.Equal(expectedResult, result);
};
await RunZipDeployAsyncTest("https://sitename.scm.azurewebsites.net", null, UserAgentVersion, responseStatusCode, verifyStep);
}
private async Task RunZipDeployAsyncTest(string publishUrl, string siteName, string userAgentVersion, HttpStatusCode responseStatusCode, Action<Mock<IHttpClient>, bool> verifyStep)
{
Mock<IHttpClient> client = new();
//constructing HttpRequestMessage to get HttpRequestHeaders as HttpRequestHeaders contains no public constructors
HttpRequestMessage requestMessage = new();
client.Setup(x => x.DefaultRequestHeaders).Returns(requestMessage.Headers);
client.Setup(c => c.PostAsync(It.IsAny<Uri>(), It.IsAny<StreamContent>())).Returns((Uri uri, StreamContent streamContent) =>
{
byte[] plainAuthBytes = Encoding.ASCII.GetBytes("username:password");
string base64AuthParam = Convert.ToBase64String(plainAuthBytes);
Assert.Equal(base64AuthParam, client.Object.DefaultRequestHeaders.Authorization.Parameter);
Assert.Equal("Basic", client.Object.DefaultRequestHeaders.Authorization.Scheme);
return Task.FromResult(new HttpResponseMessage(responseStatusCode));
});
Func<Uri, StreamContent, Task<HttpResponseMessage>> runPostAsync = (uri, streamContent) =>
{
return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK));
};
ZipDeploy zipDeployer = new();
bool result = await zipDeployer.ZipDeployAsync(TestZippedPublishContentsPath, "username", "password", publishUrl, siteName, userAgentVersion, client.Object, false);
verifyStep(client, result);
}
private bool IsStreamContentEqualToFileContent(StreamContent streamContent, string filePath)
{
byte[] expectedZipByteArr = File.ReadAllBytes(filePath);
Task<byte[]> t = streamContent.ReadAsByteArrayAsync();
t.Wait();
return expectedZipByteArr.SequenceEqual(t.Result);
}
}
}
|