69 lines
3.1 KiB
C#
69 lines
3.1 KiB
C#
using System.ComponentModel.DataAnnotations;
|
|
using MAX.Plugins;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.AspNetCore.Hosting.Server;
|
|
using Microsoft.AspNetCore.Hosting.Server.Features;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
using Store.Modules.CloudProduct;
|
|
using Store.Modules.CloudProduct.Services;
|
|
|
|
// 本地模拟站点验证服务自行创建的 HttpClient,不调用真实扣费接口。
|
|
var builder = WebApplication.CreateBuilder();
|
|
builder.Logging.ClearProviders();
|
|
builder.WebHost.UseUrls("http://127.0.0.1:0");
|
|
await using var app = builder.Build();
|
|
var calls = 0;
|
|
var status = 200;
|
|
app.MapPost("/wxxd_user/UseImageAnalysisQuota", async (HttpContext http) =>
|
|
{
|
|
calls++;
|
|
if (http.Request.Query["token"] != "key+&=?" || http.Request.Query["username"] != "用户 +&=?")
|
|
throw new Exception("查询参数编码不符合外部协议。");
|
|
http.Response.StatusCode = status;
|
|
await http.Response.WriteAsync("{\"success\":true}");
|
|
});
|
|
await app.StartAsync();
|
|
var address = app.Services.GetRequiredService<IServer>().Features.Get<IServerAddressesFeature>()!.Addresses.Single();
|
|
using var context = new PluginContext("CloudProduct", "Plugins/CloudProduct", builder.Environment);
|
|
context.Configuration["ImageAnalysisQuota:APIKey"] = "key+&=?";
|
|
var typedContext = new PluginContext<CloudProductPlugin>(context);
|
|
|
|
// 根地址带或不带末尾斜杠时,都应命中固定接口路径。
|
|
foreach (var url in new[] { address, address + "/" })
|
|
{
|
|
context.Configuration["ImageAnalysisQuota:Url"] = url;
|
|
using var service = new ImageAnalysisQuotaService(typedContext);
|
|
var body = await service.UseImageAnalysisQuotaAsync(new() { Username = "用户 +&=?" });
|
|
if (body != "{\"success\":true}") throw new Exception("应返回原始响应。");
|
|
await RejectAsync<ValidationException>(() => service.UseImageAnalysisQuotaAsync(new() { Username = " " }));
|
|
context.Configuration["ImageAnalysisQuota:APIKey"] = "";
|
|
await RejectAsync<InvalidOperationException>(() => service.UseImageAnalysisQuotaAsync(new() { Username = "test" }));
|
|
context.Configuration["ImageAnalysisQuota:APIKey"] = "key+&=?";
|
|
}
|
|
if (calls != 2) throw new Exception("无效输入或配置不能发送扣减请求。");
|
|
context.Configuration["ImageAnalysisQuota:Url"] = "file:///invalid";
|
|
await RejectAsync<InvalidOperationException>(() =>
|
|
{
|
|
using var invalid = new ImageAnalysisQuotaService(typedContext);
|
|
return Task.CompletedTask;
|
|
});
|
|
context.Configuration["ImageAnalysisQuota:Url"] = address;
|
|
using (var service = new ImageAnalysisQuotaService(typedContext))
|
|
{
|
|
status = 500;
|
|
await RejectAsync<HttpRequestException>(() => service.UseImageAnalysisQuotaAsync(new() { Username = "用户 +&=?" }));
|
|
}
|
|
if (calls != 3) throw new Exception("失败请求不能自动重试。");
|
|
await app.StopAsync();
|
|
Console.WriteLine("Image analysis quota checks passed.");
|
|
|
|
static async Task RejectAsync<T>(Func<Task> action) where T : Exception
|
|
{
|
|
try { await action(); }
|
|
catch (T) { return; }
|
|
throw new Exception($"应抛出 {typeof(T).Name}。");
|
|
}
|