Browse Source

More http methods for scripts.

pull/739/head
Sebastian 4 years ago
parent
commit
6cb9f59461
  1. 53
      backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/Extensions/HttpJintExtension.cs
  2. 113
      backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/JintScriptEngineHelperTests.cs
  3. 24
      backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/MockupHttpHandler.cs

53
backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/Extensions/HttpJintExtension.cs

@ -7,6 +7,7 @@
using System; using System;
using System.Net.Http; using System.Net.Http;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Jint; using Jint;
using Jint.Native; using Jint.Native;
@ -18,7 +19,8 @@ namespace Squidex.Domain.Apps.Core.Scripting.Extensions
{ {
public sealed class HttpJintExtension : IJintExtension public sealed class HttpJintExtension : IJintExtension
{ {
private delegate void GetJsonDelegate(string url, Action<JsValue> callback, JsValue? headers = null); private delegate void HttpJson(string url, Action<JsValue> callback, JsValue? headers = null);
private delegate void HttpJsonWithBody(string url, JsValue post, Action<JsValue> callback, JsValue? headers = null);
private readonly IHttpClientFactory httpClientFactory; private readonly IHttpClientFactory httpClientFactory;
public HttpJintExtension(IHttpClientFactory httpClientFactory) public HttpJintExtension(IHttpClientFactory httpClientFactory)
@ -28,17 +30,35 @@ namespace Squidex.Domain.Apps.Core.Scripting.Extensions
public void ExtendAsync(ExecutionContext context) public void ExtendAsync(ExecutionContext context)
{ {
var action = new GetJsonDelegate((url, callback, headers) => GetJson(context, url, callback, headers)); AddMethod(context, HttpMethod.Get, "getJSON");
AddMethod(context, HttpMethod.Delete, "deleteJSON");
context.Engine.SetValue("getJSON", action); AdBodyMethod(context, HttpMethod.Patch, "patchJSON");
AdBodyMethod(context, HttpMethod.Post, "postJSON");
AdBodyMethod(context, HttpMethod.Put, "putJSON");
} }
private void GetJson(ExecutionContext context, string url, Action<JsValue> callback, JsValue? headers) private void AddMethod(ExecutionContext context, HttpMethod method, string name)
{ {
GetJsonAsync(context, url, callback, headers).Forget(); var action = new HttpJson((url, callback, headers) =>
{
RequestAsync(context, method, url, null, callback, headers).Forget();
});
context.Engine.SetValue(name, action);
}
private void AdBodyMethod(ExecutionContext context, HttpMethod method, string name)
{
var action = new HttpJsonWithBody((url, body, callback, headers) =>
{
RequestAsync(context, method, url, body, callback, headers).Forget();
});
context.Engine.SetValue(name, action);
} }
private async Task GetJsonAsync(ExecutionContext context, string url, Action<JsValue> callback, JsValue? headers) private async Task RequestAsync(ExecutionContext context, HttpMethod method, string url, JsValue? body, Action<JsValue> callback, JsValue? headers)
{ {
if (callback == null) if (callback == null)
{ {
@ -46,7 +66,7 @@ namespace Squidex.Domain.Apps.Core.Scripting.Extensions
return; return;
} }
if (!Uri.IsWellFormedUriString(url, UriKind.Absolute)) if (!Uri.TryCreate(url, UriKind.Absolute, out var uri))
{ {
context.Fail(new JavaScriptException("URL is not valid.")); context.Fail(new JavaScriptException("URL is not valid."));
return; return;
@ -58,7 +78,7 @@ namespace Squidex.Domain.Apps.Core.Scripting.Extensions
{ {
using (var httpClient = httpClientFactory.CreateClient()) using (var httpClient = httpClientFactory.CreateClient())
{ {
using (var request = CreateRequest(url, headers)) using (var request = CreateRequest(context, method, uri, body, headers))
{ {
using (var response = await httpClient.SendAsync(request, context.CancellationToken)) using (var response = await httpClient.SendAsync(request, context.CancellationToken))
{ {
@ -79,14 +99,21 @@ namespace Squidex.Domain.Apps.Core.Scripting.Extensions
} }
} }
private static HttpRequestMessage CreateRequest(string url, JsValue? headers) private static HttpRequestMessage CreateRequest(ExecutionContext context, HttpMethod method, Uri uri, JsValue? body, JsValue? headers)
{ {
if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) var request = new HttpRequestMessage(method, uri);
if (body != null)
{ {
throw new ArgumentException("Url must be an absolute URL"); var serializer = new JsonSerializer(context.Engine);
}
var json = serializer.Serialize(body, JsValue.Undefined, JsValue.Undefined)?.ToString();
var request = new HttpRequestMessage(HttpMethod.Get, uri); if (json != null)
{
request.Content = new StringContent(json, Encoding.UTF8, "text/json");
}
}
if (headers != null && headers.Type == Types.Object) if (headers != null && headers.Type == Types.Object)
{ {

113
backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/JintScriptEngineHelperTests.cs

@ -323,7 +323,7 @@ namespace Squidex.Domain.Apps.Core.Operations.Scripting
} }
[Fact] [Fact]
public async Task Should_make_json_request() public async Task Should_make_getJson_request()
{ {
var httpHandler = SetupRequest(); var httpHandler = SetupRequest();
@ -348,7 +348,7 @@ namespace Squidex.Domain.Apps.Core.Operations.Scripting
} }
[Fact] [Fact]
public async Task Should_make_json_request_with_headers() public async Task Should_make_getJson_request_with_headers()
{ {
var httpHandler = SetupRequest(); var httpHandler = SetupRequest();
@ -379,6 +379,115 @@ namespace Squidex.Domain.Apps.Core.Operations.Scripting
Assert.Equal(expectedResult, result); Assert.Equal(expectedResult, result);
} }
[Fact]
public async Task Should_make_deleteJson_request()
{
var httpHandler = SetupRequest();
const string script = @"
var url = 'http://squidex.io';
deleteJSON(url, function(result) {
complete(result);
});
";
var vars = new ScriptVars();
var result = await sut.ExecuteAsync(vars, script);
httpHandler.ShouldBeMethod(HttpMethod.Delete);
httpHandler.ShouldBeUrl("http://squidex.io/");
var expectedResult = JsonValue.Object().Add("key", 42);
Assert.Equal(expectedResult, result);
}
[Fact]
public async Task Should_make_patchJson_request()
{
var httpHandler = SetupRequest();
const string script = @"
var url = 'http://squidex.io';
var body = { key: 42 };
patchJSON(url, body, function(result) {
complete(result);
});
";
var vars = new ScriptVars();
var result = await sut.ExecuteAsync(vars, script);
httpHandler.ShouldBeMethod(HttpMethod.Patch);
httpHandler.ShouldBeUrl("http://squidex.io/");
httpHandler.ShouldBeBody("{\"key\":42}", "text/json");
var expectedResult = JsonValue.Object().Add("key", 42);
Assert.Equal(expectedResult, result);
}
[Fact]
public async Task Should_make_postJson_request()
{
var httpHandler = SetupRequest();
const string script = @"
var url = 'http://squidex.io';
var body = { key: 42 };
postJSON(url, body, function(result) {
complete(result);
});
";
var vars = new ScriptVars();
var result = await sut.ExecuteAsync(vars, script);
httpHandler.ShouldBeMethod(HttpMethod.Post);
httpHandler.ShouldBeUrl("http://squidex.io/");
httpHandler.ShouldBeBody("{\"key\":42}", "text/json");
var expectedResult = JsonValue.Object().Add("key", 42);
Assert.Equal(expectedResult, result);
}
[Fact]
public async Task Should_make_putJson_request()
{
var httpHandler = SetupRequest();
const string script = @"
var url = 'http://squidex.io';
var body = { key: 42 };
putJSON(url, body, function(result) {
complete(result);
});
";
var vars = new ScriptVars();
var result = await sut.ExecuteAsync(vars, script);
httpHandler.ShouldBeMethod(HttpMethod.Put);
httpHandler.ShouldBeUrl("http://squidex.io/");
httpHandler.ShouldBeBody("{\"key\":42}", "text/json");
var expectedResult = JsonValue.Object().Add("key", 42);
Assert.Equal(expectedResult, result);
}
private MockupHttpHandler SetupRequest() private MockupHttpHandler SetupRequest()
{ {
var httpResponse = new HttpResponseMessage(HttpStatusCode.OK) var httpResponse = new HttpResponseMessage(HttpStatusCode.OK)

24
backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/MockupHttpHandler.cs

@ -16,21 +16,29 @@ namespace Squidex.Domain.Apps.Core.Operations.Scripting
internal sealed class MockupHttpHandler : HttpMessageHandler internal sealed class MockupHttpHandler : HttpMessageHandler
{ {
private readonly HttpResponseMessage response; private readonly HttpResponseMessage response;
private HttpRequestMessage madeRequest; private HttpRequestMessage currentRequest;
private string? currentContent;
private string? currentContentType;
public void ShouldBeMethod(HttpMethod method) public void ShouldBeMethod(HttpMethod method)
{ {
Assert.Equal(method, madeRequest.Method); Assert.Equal(method, currentRequest.Method);
} }
public void ShouldBeUrl(string url) public void ShouldBeUrl(string url)
{ {
Assert.Equal(url, madeRequest.RequestUri?.ToString()); Assert.Equal(url, currentRequest.RequestUri?.ToString());
} }
public void ShouldBeHeader(string key, string value) public void ShouldBeHeader(string key, string value)
{ {
Assert.Equal(value, madeRequest.Headers.GetValues(key).FirstOrDefault()); Assert.Equal(value, currentRequest.Headers.GetValues(key).FirstOrDefault());
}
public void ShouldBeBody(string content, string contentType)
{
Assert.Equal(content, currentContent);
Assert.Equal(contentType, currentContentType);
} }
public MockupHttpHandler(HttpResponseMessage response) public MockupHttpHandler(HttpResponseMessage response)
@ -42,7 +50,13 @@ namespace Squidex.Domain.Apps.Core.Operations.Scripting
{ {
await Task.Delay(1000, cancellationToken); await Task.Delay(1000, cancellationToken);
madeRequest = request; currentRequest = request;
if (request.Content is StringContent body)
{
currentContent = await body.ReadAsStringAsync();
currentContentType = body.Headers.ContentType?.MediaType;
}
return response; return response;
} }

Loading…
Cancel
Save