core services and tests
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
using System.Reflection;
|
||||
using QuantEngine.Infrastructure.External;
|
||||
|
||||
namespace QuantEngine.Core.Tests;
|
||||
|
||||
public class SecurityTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("/uapi/domestic-stock/v1/quotations/inquire-price", "FHKST01010100")]
|
||||
[InlineData("/uapi/domestic-stock/v1/quotations/inquire-investor", "FHKST01010900")]
|
||||
[InlineData("/uapi/domestic-stock/v1/quotations/inquire-daily-itemchartprice", "FHKST03010100")]
|
||||
public void AssertReadOnly_AllowsReadOnlyQuotationPaths(string path, string trId)
|
||||
{
|
||||
var client = CreateClient();
|
||||
|
||||
var ex = Record.Exception(() => InvokeAssertReadOnly(client, path, trId));
|
||||
|
||||
Assert.Null(ex);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("/uapi/domestic-stock/v1/trading/order-cash", "VTTC0802U")]
|
||||
[InlineData("/uapi/domestic-stock/v1/quotations/inquire-price", "TTTC084000")]
|
||||
[InlineData("/uapi/domestic-stock/v1/trading/order-cash", "FHKST01010100")]
|
||||
public void AssertReadOnly_BlocksTradingPathsOrIds(string path, string trId)
|
||||
{
|
||||
var client = CreateClient();
|
||||
|
||||
var ex = Assert.Throws<TargetInvocationException>(() => InvokeAssertReadOnly(client, path, trId));
|
||||
Assert.IsType<InvalidOperationException>(ex.InnerException);
|
||||
Assert.Contains("BLOCKED", ex.InnerException!.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AssertReadOnly_BlocksKnownTradingTrIdPrefixes()
|
||||
{
|
||||
var client = CreateClient();
|
||||
|
||||
var ex = Assert.Throws<TargetInvocationException>(() => InvokeAssertReadOnly(client, "/uapi/domestic-stock/v1/quotations/inquire-price", "VTTC8434R00"));
|
||||
Assert.IsType<InvalidOperationException>(ex.InnerException);
|
||||
Assert.Contains("TR_ID", ex.InnerException!.Message);
|
||||
}
|
||||
|
||||
private static KisApiClient CreateClient()
|
||||
{
|
||||
Environment.SetEnvironmentVariable("KIS_APP_Key_TEST", "mock-key");
|
||||
Environment.SetEnvironmentVariable("KIS_APP_Secret_TEST", "mock-secret");
|
||||
return new KisApiClient(new HttpClient(new DummyHandler()), new NoopConnectionFactory());
|
||||
}
|
||||
|
||||
private static void InvokeAssertReadOnly(KisApiClient client, string path, string trId)
|
||||
{
|
||||
var method = typeof(KisApiClient).GetMethod("AssertReadOnly", BindingFlags.Instance | BindingFlags.NonPublic)
|
||||
?? throw new InvalidOperationException("AssertReadOnly method not found.");
|
||||
method.Invoke(client, new object[] { path, trId });
|
||||
}
|
||||
|
||||
private sealed class DummyHandler : HttpMessageHandler
|
||||
{
|
||||
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
=> Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.OK));
|
||||
}
|
||||
|
||||
private sealed class NoopConnectionFactory : QuantEngine.Infrastructure.Data.IDbConnectionFactory
|
||||
{
|
||||
public System.Data.IDbConnection CreateConnection() => throw new NotSupportedException("Not needed for read-only guard tests.");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user