137 lines
5.2 KiB
C#
137 lines
5.2 KiB
C#
using System.Text;
|
|
using System.Threading;
|
|
using MCPForUnity.Editor.Services.AssetGen.Http;
|
|
using MCPForUnity.Editor.Services.AssetGen.Providers;
|
|
using NUnit.Framework;
|
|
|
|
namespace MCPForUnityTests.Editor.AssetGen
|
|
{
|
|
/// <summary>
|
|
/// Exercises the Tripo adapter against a <see cref="FakeHttpTransport"/> — no network.
|
|
/// Asserts request shaping (endpoint, method, auth scheme, body) and poll-state mapping.
|
|
/// The bearer secret is never asserted beyond the "Bearer " scheme prefix.
|
|
/// </summary>
|
|
public class TripoAdapterTests
|
|
{
|
|
private static HttpResult Json(string json, int status = 200)
|
|
=> new HttpResult
|
|
{
|
|
Status = status,
|
|
IsSuccess = status >= 200 && status < 300,
|
|
Text = json,
|
|
Body = Encoding.UTF8.GetBytes(json)
|
|
};
|
|
|
|
[Test]
|
|
public void Submit_PostsTaskEndpoint_WithBearerHeader_AndReturnsTaskId()
|
|
{
|
|
var http = new FakeHttpTransport
|
|
{
|
|
Handler = _ => Json("{\"code\":0,\"data\":{\"task_id\":\"abc123\"}}")
|
|
};
|
|
var adapter = new TripoAdapter();
|
|
var req = new ModelGenRequest { Provider = "tripo", Mode = "text", Prompt = "a red dragon" };
|
|
|
|
string taskId = adapter.SubmitAsync(req, "tsk_secret_value", http, CancellationToken.None)
|
|
.GetAwaiter().GetResult();
|
|
|
|
Assert.AreEqual("abc123", taskId);
|
|
Assert.AreEqual(1, http.RecordedRequests.Count);
|
|
|
|
HttpRequestSpec rec = http.RecordedRequests[0];
|
|
StringAssert.Contains("/v2/openapi/task", rec.Url);
|
|
Assert.AreEqual("POST", rec.Method);
|
|
Assert.IsTrue(rec.Headers.ContainsKey("Authorization"));
|
|
StringAssert.StartsWith("Bearer ", rec.Headers["Authorization"]);
|
|
|
|
string body = Encoding.UTF8.GetString(rec.Body);
|
|
StringAssert.Contains("a red dragon", body);
|
|
StringAssert.Contains("text_to_model", body);
|
|
}
|
|
|
|
[Test]
|
|
public void Poll_MapsSuccess_WithDownloadUrl()
|
|
{
|
|
var http = new FakeHttpTransport
|
|
{
|
|
Handler = _ => Json(
|
|
"{\"code\":0,\"data\":{\"status\":\"success\",\"progress\":100," +
|
|
"\"output\":{\"pbr_model\":\"https://cdn.tripo3d.ai/model.glb\"}}}")
|
|
};
|
|
var adapter = new TripoAdapter();
|
|
|
|
ProviderPollResult res = adapter.PollAsync("abc123", "tsk_secret_value", http, CancellationToken.None)
|
|
.GetAwaiter().GetResult();
|
|
|
|
Assert.AreEqual(ProviderPollState.Succeeded, res.State);
|
|
Assert.AreEqual("https://cdn.tripo3d.ai/model.glb", res.DownloadUrl);
|
|
}
|
|
|
|
[Test]
|
|
public void Poll_MapsRunning_WithProgress()
|
|
{
|
|
var http = new FakeHttpTransport
|
|
{
|
|
Handler = _ => Json("{\"code\":0,\"data\":{\"status\":\"running\",\"progress\":42}}")
|
|
};
|
|
var adapter = new TripoAdapter();
|
|
|
|
ProviderPollResult res = adapter.PollAsync("abc123", "k", http, CancellationToken.None)
|
|
.GetAwaiter().GetResult();
|
|
|
|
Assert.AreEqual(ProviderPollState.Running, res.State);
|
|
Assert.AreEqual(0.42f, res.Progress, 0.001f);
|
|
}
|
|
|
|
[Test]
|
|
public void Poll_MapsFailed_WithError()
|
|
{
|
|
var http = new FakeHttpTransport
|
|
{
|
|
Handler = _ => Json("{\"code\":0,\"data\":{\"status\":\"failed\",\"progress\":0}}")
|
|
};
|
|
var adapter = new TripoAdapter();
|
|
|
|
ProviderPollResult res = adapter.PollAsync("abc123", "k", http, CancellationToken.None)
|
|
.GetAwaiter().GetResult();
|
|
|
|
Assert.AreEqual(ProviderPollState.Failed, res.State);
|
|
Assert.IsNotEmpty(res.Error);
|
|
}
|
|
|
|
[Test]
|
|
public void Submit_ImageMode_UsesImageToModel()
|
|
{
|
|
var http = new FakeHttpTransport
|
|
{
|
|
Handler = _ => Json("{\"code\":0,\"data\":{\"task_id\":\"img1\"}}")
|
|
};
|
|
var adapter = new TripoAdapter();
|
|
var req = new ModelGenRequest
|
|
{
|
|
Provider = "tripo",
|
|
Mode = "image",
|
|
ImageUrl = "https://example.com/in.png"
|
|
};
|
|
|
|
adapter.SubmitAsync(req, "k", http, CancellationToken.None).GetAwaiter().GetResult();
|
|
|
|
string body = Encoding.UTF8.GetString(http.RecordedRequests[0].Body);
|
|
StringAssert.Contains("image_to_model", body);
|
|
StringAssert.Contains("https://example.com/in.png", body);
|
|
}
|
|
|
|
[Test]
|
|
public void Submit_ImageMode_LocalPathOnly_Throws()
|
|
{
|
|
// Tripo can't take a local image inline (no data-URI support, upload not wired) — it must
|
|
// fail clearly rather than silently falling back to text mode.
|
|
var adapter = new TripoAdapter();
|
|
var req = new ModelGenRequest { Provider = "tripo", Mode = "image", ImagePath = "/tmp/whatever.png" };
|
|
|
|
Assert.Throws<System.Exception>(() =>
|
|
adapter.SubmitAsync(req, "k", new FakeHttpTransport(), CancellationToken.None).GetAwaiter().GetResult());
|
|
}
|
|
}
|
|
}
|