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.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Jint;
using Jint.Native;
@ -18,7 +19,8 @@ namespace Squidex.Domain.Apps.Core.Scripting.Extensions
{
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;
public HttpJintExtension(IHttpClientFactory httpClientFactory)
@ -28,17 +30,35 @@ namespace Squidex.Domain.Apps.Core.Scripting.Extensions
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)
{
@ -46,7 +66,7 @@ namespace Squidex.Domain.Apps.Core.Scripting.Extensions
return;
}
if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
if (!Uri.TryCreate(url, UriKind.Absolute, out var uri))
{
context.Fail(new JavaScriptException("URL is not valid."));
return;
@ -58,7 +78,7 @@ namespace Squidex.Domain.Apps.Core.Scripting.Extensions
{
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))
{
@ -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)
{

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

@ -323,7 +323,7 @@ namespace Squidex.Domain.Apps.Core.Operations.Scripting
}
[Fact]
public async Task Should_make_json_request()
public async Task Should_make_getJson_request()
{
var httpHandler = SetupRequest();
@ -348,7 +348,7 @@ namespace Squidex.Domain.Apps.Core.Operations.Scripting
}
[Fact]
public async Task Should_make_json_request_with_headers()
public async Task Should_make_getJson_request_with_headers()
{
var httpHandler = SetupRequest();
@ -379,6 +379,115 @@ namespace Squidex.Domain.Apps.Core.Operations.Scripting
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()
{
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
{
private readonly HttpResponseMessage response;
private HttpRequestMessage madeRequest;
private HttpRequestMessage currentRequest;
private string? currentContent;
private string? currentContentType;
public void ShouldBeMethod(HttpMethod method)
{
Assert.Equal(method, madeRequest.Method);
Assert.Equal(method, currentRequest.Method);
}
public void ShouldBeUrl(string url)
{
Assert.Equal(url, madeRequest.RequestUri?.ToString());
Assert.Equal(url, currentRequest.RequestUri?.ToString());
}
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)
@ -42,7 +50,13 @@ namespace Squidex.Domain.Apps.Core.Operations.Scripting
{
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;
}

Loading…
Cancel
Save