Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#57 implement missing api endpoints #65

Merged
merged 13 commits into from
Aug 11, 2022
12 changes: 6 additions & 6 deletions Billbee.Api.Client.Demo/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Billbee.Api.Client.Demo
///
/// To use this demo, you have to enable the API in your account. Please refer to https://www.billbee.de/api/ for further information.
/// </summary>
internal class Program
internal static class Program
{
private static int Main()
{
Expand Down Expand Up @@ -91,7 +91,7 @@ private static int Main()
// Requesting a specific webhook
if (webHooks.Count > 0)
{
var webhook = client.Webhooks.GetWebhook(webHooks.FirstOrDefault().Id);
var webhook = client.Webhooks.GetWebhook(webHooks.FirstOrDefault()!.Id);

// Updating webhook
webhook.IsPaused = false;
Expand All @@ -117,7 +117,7 @@ private static int Main()

if (customFields.Data.Count > 0)
{
var firstCustomField = client.Products.GetCustomField(customFields.Data.First().Id.Value);
var firstCustomField = client.Products.GetCustomField(customFields.Data.First()!.Id!.Value);
}

// Artificial brake to prevent throttling
Expand Down Expand Up @@ -177,7 +177,7 @@ private static int Main()

if (products.Data.Count > 0)
{
var articleId = products.Data.First().Id.Value;
var articleId = products.Data.First()!.Id!.Value;

var articleImages = client.Products.GetArticleImages(articleId);

Expand Down Expand Up @@ -221,7 +221,7 @@ private static int Main()

if (customers.Data.Count > 0)
{
var customer = client.Customer.GetCustomer(customers.Data.First().Id.Value);
var customer = client.Customer.GetCustomer(customers.Data.First()!.Id!.Value);

customer.Data.Name = "Tobias Tester";

Expand All @@ -230,7 +230,7 @@ private static int Main()
// Artificial brake to prevent throttling
Thread.Sleep(1000);

var customerOrder = client.Customer.GetOrdersForCustomer(customer.Data.Id.Value, 1, 50);
var customerOrder = client.Customer.GetOrdersForCustomer(customer.Data.Id!.Value, 1, 50);
var customerAddresses = client.Customer.GetAddressesForCustomer(customer.Data.Id.Value, 1, 50);
}

Expand Down
1 change: 1 addition & 0 deletions Billbee.Api.Client.Test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
config.prod.json
152 changes: 152 additions & 0 deletions Billbee.Api.Client.Test/ApiClientTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
using System.Reflection;
using System.Text;
using Billbee.Api.Client.EndPoint;
using Billbee.Api.Client.Enums;

namespace Billbee.Api.Client.Test;

[TestClass]
public class ApiClientTest
{
[TestMethod]
public void ApiClient_Init_Test()
{
var uut = new ApiClient();

Assert.IsNotNull(uut);
Assert.IsNotNull(uut.Configuration);
Assert.IsNull(uut.Configuration.Username);
Assert.IsNull(uut.Configuration.Password);
Assert.IsNull(uut.Configuration.ApiKey);
Assert.AreEqual("https://app.billbee.io/api/v1", uut.Configuration.BaseUrl);
Assert.AreEqual(ErrorHandlingEnum.ThrowException, uut.Configuration.ErrorHandlingBehaviour);

Assert.IsNotNull(uut.AutomaticProvision);
Assert.IsNotNull(uut.CloudStorages);
Assert.IsNotNull(uut.Customer);
Assert.IsNotNull(uut.Events);
Assert.IsNotNull(uut.Orders);
Assert.IsNotNull(uut.Products);
Assert.IsNotNull(uut.Search);
Assert.IsNotNull(uut.Shipment);
Assert.IsNotNull(uut.Webhooks);
}

[TestMethod]
public void ApiClient_InitWithConfig_Test()
{
var config = new ApiConfiguration
{
Username = "myUser",
Password = "myPwd",
ApiKey = "myApiKey",
BaseUrl = "myBaseUrl",
ErrorHandlingBehaviour = ErrorHandlingEnum.ReturnErrorContent
};

var uut = new ApiClient(config);

Assert.IsNotNull(uut);
Assert.IsNotNull(uut.Configuration);
Assert.AreEqual("myUser", uut.Configuration.Username);
Assert.AreEqual("myPwd", uut.Configuration.Password);
Assert.AreEqual("myApiKey", uut.Configuration.ApiKey);
Assert.AreEqual("myBaseUrl", uut.Configuration.BaseUrl);
Assert.AreEqual(ErrorHandlingEnum.ReturnErrorContent, uut.Configuration.ErrorHandlingBehaviour);
}

[TestMethod]
public void ApiClient_InitWithConfigFile_Test()
{
var fiDll = new FileInfo(Assembly.GetExecutingAssembly().Location);
Assert.IsNotNull(fiDll);
Assert.IsNotNull(fiDll.Directory);
var path = Path.Combine(fiDll.Directory.FullName, "../../../config.test");
var uut = new ApiClient(path);

Assert.IsNotNull(uut);
Assert.IsNotNull(uut.Configuration);
Assert.AreEqual("myUserFromFile", uut.Configuration.Username);
Assert.AreEqual("myPwdFromFile", uut.Configuration.Password);
Assert.AreEqual("myApiKeyFromFile", uut.Configuration.ApiKey);
Assert.AreEqual("myBaseUrlFromFile", uut.Configuration.BaseUrl);
Assert.AreEqual(ErrorHandlingEnum.ReturnErrorContent, uut.Configuration.ErrorHandlingBehaviour);
}

private class TypeMapping
{
public TypeMapping(string uutClass, string uutTypeName, string testTypeName, bool foundMapping)
{
UutClass = uutClass;
UutTypeName = uutTypeName;
TestTypeName = testTypeName;
FoundMapping = foundMapping;
}

public string UutClass { get; }
public string UutTypeName { get; }
public string TestTypeName { get; }
public bool FoundMapping { get; }
}

[TestMethod]
public void CheckAllTests_UnitTestsForAllEndpointsTest()
{
_checkTestMethods("Test", "_Test");
}

[TestMethod]
public void CheckAllTests_IntegrationTestsForAllEndpointsTest()
{
_checkTestMethods( "IntegrationTest", "_IntegrationTest");
}

private void _checkTestMethods(string testClassPostfix, string testMethodPostfix)
{
var clientAssembly = Assembly.Load("Billbee.Api.Client");
var clientTypes = clientAssembly.GetTypes();
var testAssembly = Assembly.GetExecutingAssembly();
var testTypes = testAssembly.GetTypes();

var typeMappingsTestMethods = new List<TypeMapping>();
foreach (var clientType in clientTypes)
{
var clientTypeName = clientType.Name;
if (clientType.Namespace == null || !clientType.Namespace.StartsWith("Billbee.Api.Client.EndPoint"))
{
continue;
}

var entityNamePrefix = clientTypeName.Substring(0, clientTypeName.IndexOf("EndPoint")) + "_";

var testTypeName = clientType.Name + testClassPostfix;
var testType = testTypes.FirstOrDefault(t => t.IsClass && t.IsPublic && t.Name == testTypeName && t.GetCustomAttributes().Any(a => a is TestClassAttribute));
Assert.IsNotNull(testType);

var bindingFlags = BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance;
var clientMethods = clientType.GetMethods(bindingFlags);
var testMethods = testType.GetMethods(bindingFlags).Where(m => m.GetCustomAttributes().Any(a => a is TestMethodAttribute)).ToList();
foreach (var clientMethod in clientMethods)
{
var clientMethodName = clientMethod.Name;

var testMethodName = entityNamePrefix + clientMethodName + testMethodPostfix;
var foundMapping = testMethods.Any(t => t.Name == testMethodName);
if (clientTypeName != nameof(EnumEndPoint))
{
typeMappingsTestMethods.Add(new TypeMapping(clientTypeName, clientMethodName, testMethodName, foundMapping));
}
}
}

Console.WriteLine($"#SdkMethods={typeMappingsTestMethods.Count}, #{testMethodPostfix}Methods={typeMappingsTestMethods.Count(t => t.FoundMapping)}");
Console.WriteLine();
Console.WriteLine($"Test implemented,ClassName,UutTypeName,TestTypeName");
foreach (var typeMapping in typeMappingsTestMethods)
{
Console.WriteLine($"{typeMapping.FoundMapping},{typeMapping.UutClass},{typeMapping.UutTypeName},{typeMapping.TestTypeName}");
}

Assert.IsTrue(typeMappingsTestMethods.All(t => t.FoundMapping));
}
}
116 changes: 116 additions & 0 deletions Billbee.Api.Client.Test/ApiSyncTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
using System.Diagnostics;
using System.Reflection;
using Microsoft.OpenApi;
using Microsoft.OpenApi.Extensions;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Readers;

namespace Billbee.Api.Client.Test;

[TestClass]
public class ApiSyncTest
{
[DebuggerDisplay("{Path}:{HttpOperation}")]
public class ApiOperation
{
public string Path { get; set; } = null!;
public HttpOperation HttpOperation { get; set; }

public override string ToString() => $"{Path}:{HttpOperation}";
}

[TestMethod]
public async Task Api_SyncCheck_Test()
{
var sdkOps = GetSdkOperations();
var apiOps = await GetApiOperations();

var missingSdkOps = new List<ApiOperation>();
foreach (var apiOp in apiOps)
{
if (!sdkOps.Any(sdkOp => sdkOp.Path == apiOp.Path && sdkOp.HttpOperation == apiOp.HttpOperation))
{
missingSdkOps.Add(apiOp);
}
}

Console.WriteLine($"#ApiOps={apiOps.Count}, #SdkOps={sdkOps.Count}, #MissingSdkOps={missingSdkOps.Count}");

if (missingSdkOps.Count > 0)
{
Console.WriteLine("Missing Sdk Operations:");
foreach (var missingSdkOp in missingSdkOps)
{
Console.WriteLine(missingSdkOp.ToString());
}
}

Assert.AreEqual(0, missingSdkOps.Count);
}

private async Task<List<ApiOperation>> GetApiOperations()
{
var apiOps = new List<ApiOperation>();
var openApiDoc = await GetOpenApiDoc();
foreach (var path in openApiDoc.Paths)
{
foreach (var op in path.Value.Operations)
{
if (Enum.TryParse(op.Key.ToString(), out HttpOperation httpOperation))
{
var apiOp = new ApiOperation
{
Path = path.Key,
HttpOperation = httpOperation
};
apiOps.Add(apiOp);
}
else
{
Assert.Fail("unknown Path.OperationType");
}
}
}

return apiOps;
}

private static List<ApiOperation> GetSdkOperations()
{
var sdkOps = new List<ApiOperation>();
var endpointTypes = Assembly.GetAssembly(typeof(ApiClient))?.GetTypes()
.Where(t => t.Namespace == "Billbee.Api.Client.EndPoint");
Assert.IsNotNull(endpointTypes);
foreach (var endpoint in endpointTypes)
{
foreach (var methodInfo in endpoint.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic |
BindingFlags.Public))
{
if (methodInfo.GetCustomAttributes(true).FirstOrDefault(x => x is ApiMappingAttribute) is
ApiMappingAttribute apiMappingAttr)
{
var op = new ApiOperation
{
Path = apiMappingAttr.ApiPath,
HttpOperation = apiMappingAttr.HttpOperation
};
sdkOps.Add(op);
}
}
}

return sdkOps;
}

private async Task<OpenApiDocument> GetOpenApiDoc()
{
var httpClient = new HttpClient
{
BaseAddress = new Uri("https://app.billbee.io/")
};

var stream = await httpClient.GetStreamAsync("/swagger/docs/v1");

return new OpenApiStreamReader().Read(stream, out var diagnostic);
}
}
Loading