Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions eng/Generate.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ $cadlRanchProjectDirectory = Join-Path $repoRoot 'test' 'CadlRanchProjects'
$cadlRanchProjectPaths =
'authentication/api-key',
'authentication/oauth2',
'authentication/union',
'models/property-optional',
'models/property-types',
'models/usage'
Expand Down
4 changes: 4 additions & 0 deletions src/AutoRest.CSharp/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@
"commandName": "Project",
"commandLineArgs": "--standalone $(SolutionDir)\\test\\CadlRanchProjects\\authentication\\oauth2\\Generated"
},
"cadl-authentication/union": {
"commandName": "Project",
"commandLineArgs": "--standalone $(SolutionDir)\\test\\CadlRanchProjects\\authentication\\union\\Generated"
},
"cadl-models/property-optional": {
"commandName": "Project",
"commandLineArgs": "--standalone $(SolutionDir)\\test\\CadlRanchProjects\\models\\property-optional\\Generated"
Expand Down
102 changes: 102 additions & 0 deletions test/CadlRanchProjects.Tests/OAuth2TestHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Azure.Core.Pipeline;
using Azure.Core;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
using System.Threading.Tasks;
using System.Threading;
using System;

namespace CadlRanchProjects.Tests
{
public class OAuth2TestHelper
{
public class MockCredential : TokenCredential
{
public override ValueTask<AccessToken> GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken)
{
return new(GetToken(requestContext, cancellationToken));
}

public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken)
{
return new AccessToken(string.Join(" ", requestContext.Scopes), DateTimeOffset.MaxValue);
}
}

// Only for bypassing HTTPS check purpose
public class MockBearerTokenAuthenticationPolicy : BearerTokenAuthenticationPolicy
{
private readonly HttpPipelineTransport _transport;

public MockBearerTokenAuthenticationPolicy(TokenCredential credential, IEnumerable<string> scopes, HttpPipelineTransport transport) : base(credential, scopes)
{
_transport = transport;
}

public override ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemory<HttpPipelinePolicy> pipeline)
{
return ProcessAsync(message, pipeline, true);
}

public override void Process(HttpMessage message, ReadOnlyMemory<HttpPipelinePolicy> pipeline)
{
ProcessAsync(message, pipeline, false).EnsureCompleted();
}

protected new async ValueTask ProcessNextAsync(HttpMessage message, ReadOnlyMemory<HttpPipelinePolicy> pipeline)
{
await _transport.ProcessAsync(message).ConfigureAwait(false);

var response = message.Response;
Type responseType = response.GetType();
PropertyInfo propInfo = responseType.GetProperty("IsError", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
propInfo.SetValue(response, message.ResponseClassifier.IsErrorResponse(message));
}

protected new void ProcessNext(HttpMessage message, ReadOnlyMemory<HttpPipelinePolicy> pipeline)
{
_transport.Process(message);
}

private async ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemory<HttpPipelinePolicy> pipeline, bool async)
{
if (async)
{
await AuthorizeRequestAsync(message).ConfigureAwait(false);
await ProcessNextAsync(message, pipeline).ConfigureAwait(false);
}
else
{
AuthorizeRequest(message);
ProcessNext(message, pipeline);
}

// Check if we have received a challenge or we have not yet issued the first request.
if (message.Response.Status == (int)HttpStatusCode.Unauthorized && message.Response.Headers.Contains(HttpHeader.Names.WwwAuthenticate))
{
// Attempt to get the TokenRequestContext based on the challenge.
// If we fail to get the context, the challenge was not present or invalid.
// If we succeed in getting the context, authenticate the request and pass it up the policy chain.
if (async)
{
if (await AuthorizeRequestOnChallengeAsync(message).ConfigureAwait(false))
{
await ProcessNextAsync(message, pipeline).ConfigureAwait(false);
}
}
else
{
if (AuthorizeRequestOnChallenge(message))
{
ProcessNext(message, pipeline);
}
}
}
}
}
}
}
92 changes: 1 addition & 91 deletions test/CadlRanchProjects.Tests/authentication-oauth2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,9 @@
using Azure;
using NUnit.Framework;
using Authentication.OAuth2;
using Azure.Core.Pipeline;
using Azure.Core;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using System;
using System.Reflection;
using NUnit.Framework.Internal;
using static CadlRanchProjects.Tests.OAuth2TestHelper;

namespace CadlRanchProjects.Tests
{
Expand All @@ -38,90 +33,5 @@ public Task Authentication_OAuth2_invalid() => Test((host) =>
Assert.AreEqual(403, exception.Status);
return Task.CompletedTask;
});

public class MockCredential : TokenCredential
{
public override ValueTask<AccessToken> GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken)
{
return new(GetToken(requestContext, cancellationToken));
}

public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken)
{
return new AccessToken(string.Join(" ", requestContext.Scopes), DateTimeOffset.MaxValue);
}
}

// Only for bypassing HTTPS check purpose
public class MockBearerTokenAuthenticationPolicy : BearerTokenAuthenticationPolicy
{
private readonly HttpPipelineTransport _transport;

public MockBearerTokenAuthenticationPolicy(TokenCredential credential, IEnumerable<string> scopes, HttpPipelineTransport transport) : base(credential, scopes)
{
_transport = transport;
}

public override ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemory<HttpPipelinePolicy> pipeline)
{
return ProcessAsync(message, pipeline, true);
}

public override void Process(HttpMessage message, ReadOnlyMemory<HttpPipelinePolicy> pipeline)
{
ProcessAsync(message, pipeline, false).EnsureCompleted();
}

protected new async ValueTask ProcessNextAsync(HttpMessage message, ReadOnlyMemory<HttpPipelinePolicy> pipeline)
{
await _transport.ProcessAsync(message).ConfigureAwait(false);

var response = message.Response;
Type responseType = response.GetType();
PropertyInfo propInfo = responseType.GetProperty("IsError", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
propInfo.SetValue(response, message.ResponseClassifier.IsErrorResponse(message));
}

protected new void ProcessNext(HttpMessage message, ReadOnlyMemory<HttpPipelinePolicy> pipeline)
{
_transport.Process(message);
}

private async ValueTask ProcessAsync(HttpMessage message, ReadOnlyMemory<HttpPipelinePolicy> pipeline, bool async)
{
if (async)
{
await AuthorizeRequestAsync(message).ConfigureAwait(false);
await ProcessNextAsync(message, pipeline).ConfigureAwait(false);
}
else
{
AuthorizeRequest(message);
ProcessNext(message, pipeline);
}

// Check if we have received a challenge or we have not yet issued the first request.
if (message.Response.Status == (int)HttpStatusCode.Unauthorized && message.Response.Headers.Contains(HttpHeader.Names.WwwAuthenticate))
{
// Attempt to get the TokenRequestContext based on the challenge.
// If we fail to get the context, the challenge was not present or invalid.
// If we succeed in getting the context, authenticate the request and pass it up the policy chain.
if (async)
{
if (await AuthorizeRequestOnChallengeAsync(message).ConfigureAwait(false))
{
await ProcessNextAsync(message, pipeline).ConfigureAwait(false);
}
}
else
{
if (AuthorizeRequestOnChallenge(message))
{
ProcessNext(message, pipeline);
}
}
}
}
}
}
}
32 changes: 32 additions & 0 deletions test/CadlRanchProjects.Tests/authentication-union.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.Threading.Tasks;
using Authentication.Union;
using AutoRest.TestServer.Tests.Infrastructure;
using Azure;
using Azure.Core;
using NUnit.Framework;
using static CadlRanchProjects.Tests.OAuth2TestHelper;

namespace CadlRanchProjects.Tests
{
public class AuthenticationUnionTests : CadlRanchTestBase
{
[Test]
public Task Authentication_Union_validKey() => Test(async (host) =>
{
Response response = await new UnionClient(new AzureKeyCredential("valid-key"), host, null).ValidKeyAsync();
Assert.AreEqual(204, response.Status);
});

[Test]
public Task Authentication_Union_validToken() => Test(async (host) =>
{
var options = new UnionClientOptions();
options.AddPolicy(new MockBearerTokenAuthenticationPolicy(new MockCredential(), UnionClient.TokenScopes, options.Transport), HttpPipelinePosition.PerCall);
Response response = await new UnionClient(new MockCredential(), host, options).ValidTokenAsync();
Assert.AreEqual(204, response.Status);
});
}
}
38 changes: 37 additions & 1 deletion test/CadlRanchProjects.Tests/models-property-optional.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ public Task Models_Property_Optional_Datetime_getDefault() => Test(async (host)
});

[Test]
[Ignore("Need cadl ranch fix")]
public Task Models_Property_Optional_Datetime_putAll() => Test(async (host) =>
{
DatetimeProperty data = new()
Expand Down Expand Up @@ -210,5 +209,42 @@ public Task Models_Property_Optional_CollectionsModel_putDefault() => Test(async
Response response = await new OptionalClient(host, null).GetCollectionsModelClient().PutDefaultAsync(new CollectionsModelProperty().ToRequestContent());
Assert.AreEqual(204, response.Status);
});

[Test]
public Task Models_Property_Optional_RequiredAndOptional_getAll() => Test(async (host) =>
{
Response response = await new OptionalClient(host, null).GetRequiredAndOptionalClient().GetAllAsync();
var result = RequiredAndOptionalProperty.FromResponse(response);
Assert.AreEqual("hello", result.OptionalProperty);
Assert.AreEqual(42, result.RequiredProperty);
});

[Test]
public Task Models_Property_Optional_RequiredAndOptional_getRequiredOnly() => Test(async (host) =>
{
Response response = await new OptionalClient(host, null).GetRequiredAndOptionalClient().GetRequiredOnlyAsync();
var result = RequiredAndOptionalProperty.FromResponse(response);
Assert.AreEqual(null, result.OptionalProperty);
Assert.AreEqual(42, result.RequiredProperty);
});

[Test]
public Task Models_Property_Optional_RequiredAndOptional_putAll() => Test(async (host) =>
{
var content = new RequiredAndOptionalProperty(42)
{
OptionalProperty = "hello"
};

Response response = await new OptionalClient(host, null).GetRequiredAndOptionalClient().PutAllAsync(content.ToRequestContent());
Assert.AreEqual(204, response.Status);
});

[Test]
public Task Models_Property_Optional_RequiredAndOptional_putRequiredOnly() => Test(async (host) =>
{
Response response = await new OptionalClient(host, null).GetRequiredAndOptionalClient().PutRequiredOnlyAsync(new RequiredAndOptionalProperty(42));
Assert.AreEqual(204, response.Status);
});
}
}
15 changes: 15 additions & 0 deletions test/CadlRanchProjects.Tests/models-property-types.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,5 +214,20 @@ public Task Models_Property_Types_DictionaryString_put() => Test(async (host) =>
Response response = await new TypesClient(host, null).GetDictionaryStringClient().PutAsync(new DictionaryStringProperty(new Dictionary<string, string> { ["k1"] = "hello", ["k2"] = "world" }).ToRequestContent());
Assert.AreEqual(204, response.Status);
});

[Test]
public Task Models_Property_Types_Never_get() => Test(async (host) =>
{
Response response = await new TypesClient(host, null).GetNeverClient().GetNeverAsync();
var result = NeverProperty.FromResponse(response);
Assert.NotNull(result);
});

[Test]
public Task Models_Property_Types_Never_put() => Test(async (host) =>
{
Response response = await new TypesClient(host, null).GetNeverClient().PutAsync(new NeverProperty().ToRequestContent());
Assert.AreEqual(204, response.Status);
});
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<doc>
<members>
<member name="ValidKeyAsync(RequestContext)">
<example>
This sample shows how to call ValidKeyAsync.
<code><![CDATA[
var credential = new AzureKeyCredential("<key>");
var client = new UnionClient(credential);

Response response = await client.ValidKeyAsync();
Console.WriteLine(response.Status);
]]></code>
</example>
</member>
<member name="ValidKey(RequestContext)">
<example>
This sample shows how to call ValidKey.
<code><![CDATA[
var credential = new AzureKeyCredential("<key>");
var client = new UnionClient(credential);

Response response = client.ValidKey();
Console.WriteLine(response.Status);
]]></code>
</example>
</member>
<member name="ValidTokenAsync(RequestContext)">
<example>
This sample shows how to call ValidTokenAsync.
<code><![CDATA[
var credential = new AzureKeyCredential("<key>");
var client = new UnionClient(credential);

Response response = await client.ValidTokenAsync();
Console.WriteLine(response.Status);
]]></code>
</example>
</member>
<member name="ValidToken(RequestContext)">
<example>
This sample shows how to call ValidToken.
<code><![CDATA[
var credential = new AzureKeyCredential("<key>");
var client = new UnionClient(credential);

Response response = client.ValidToken();
Console.WriteLine(response.Status);
]]></code>
</example>
</member>
</members>
</doc>
Loading