Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update the jint options to support System.text.json #15449

Merged
merged 14 commits into from
Mar 14, 2024
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text.Json.Nodes;
using Jint;
using Jint.Runtime.Interop;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.FileProviders;

Expand All @@ -19,7 +22,34 @@ public JavaScriptEngine(IMemoryCache memoryCache)

public IScriptingScope CreateScope(IEnumerable<GlobalMethod> methods, IServiceProvider serviceProvider, IFileProvider fileProvider, string basePath)
{
var engine = new Engine();
var engine = new Engine(options =>
{
// make JsonArray behave like JS array
options.Interop.WrapObjectHandler = static (e, target, type) =>
{
var wrapped = new ObjectWrapper(e, target);
if (target is JsonArray)
{
wrapped.Prototype = e.Intrinsics.Array.PrototypeObject;
}
return wrapped;
};

// we cannot access this[string] with anything else than JsonObject, otherwise itw will throw
hyzx86 marked this conversation as resolved.
Show resolved Hide resolved
options.Interop.TypeResolver = new TypeResolver
{
MemberFilter = static info =>
{
if (info.ReflectedType != typeof(JsonObject) && info.Name == "Item" && info is PropertyInfo p)
{
var parameters = p.GetIndexParameters();
return parameters.Length != 1 || parameters[0].ParameterType != typeof(string);
}

return true;
}
};
});

foreach (var method in methods)
{
Expand Down
112 changes: 112 additions & 0 deletions test/OrchardCore.Tests/Scripting/ScriptFunctionsTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
using System.Text.Json;
using System.Text.Json.Nodes;
using OrchardCore.Scripting;
using OrchardCore.Tests.Apis.Context;
using OrchardCore.Users;
using OrchardCore.Users.Models;

namespace OrchardCore.Tests.Scripting;
public class ScriptFunctionsTest
{
[Fact]
public async Task ProcessUserInfoTest()
hyzx86 marked this conversation as resolved.
Show resolved Hide resolved
{
using var context = new SiteContext();
await context.InitializeAsync();
await context.UsingTenantScopeAsync(async scope =>
{
var userProperties = @"{
""UserProfile"": {
""ContentItemId"": ""4fkpnj0fnawmzy3zdc5kx5pnn1"",
""ContentItemVersionId"": null,
""ContentType"": ""UserProfile"",
""DisplayText"": ""admin admin - (admin)"",
""Latest"": true,
""Published"": true,
""ModifiedUtc"": null,
""PublishedUtc"": null,
""CreatedUtc"": null,
""Owner"": ""4fkpnj0fnawmzy3zdc5kx5pnn1"",
""Author"": ""admin"",
""UserProfile"": {
""UserName"": {
""Text"": ""admin""
},
""Email"": {
""Text"": ""[email protected]""
},
""OwnerUser"": {
""UserIds"": [
""4fkpnj0fnawmzy3zdc5kx5pnn1""
],
""UserNames"": []
},
""DisplayName"": {
""Text"": ""admin admin""
},
""Department"": {
""ContentItemIds"": []
},
""Manager"": {
""UserIds"": [],
""UserNames"": []
},
""FirstName"": {
""Text"": null
},
""LastName"": {
""Text"": null
},
""Country"": {
""Text"": ""ID""
},
""Countries"": {
""Values"": []
}
},
""TitlePart"": {
""Title"": ""admin - (admin)""
},
""DIndexPart"": {}
},
""UserNotificationPreferencesPart"": {
""Methods"": [
""Email""
],
""Optout"": []
},
""UserTimeZone"": {
""TimeZoneId"": null
}
}";

var userManager = scope.ServiceProvider.GetRequiredService<UserManager<IUser>>();
hyzx86 marked this conversation as resolved.
Show resolved Hide resolved
var user = await userManager.FindByNameAsync("admin") as User;
user.Properties = JObject.Parse(userProperties);
await userManager.UpdateAsync(user);

var findUser = new GlobalMethod
{
Name = "getUserByName",
Method = sp => (string userName) =>
{
var userManager = sp.GetRequiredService<UserManager<IUser>>();
var userInfo = userManager.FindByNameAsync(userName).GetAwaiter().GetResult();
var jobjUser = JObject.FromObject(userInfo, JOptions.CamelCase);
jobjUser.Remove("securityStamp");
jobjUser.Remove("passwordHash");
jobjUser.Remove("resetToken");
jobjUser.Remove("userTokens");
return jobjUser;
}
};

var scriptingEngine = scope.ServiceProvider.GetRequiredService<IScriptingEngine>();
var scriptingScope = scriptingEngine.CreateScope([findUser], scope.ServiceProvider, null, null);
var result = (bool)scriptingEngine.Evaluate(scriptingScope, "var user = getUserByName('admin'); return user.userName == 'admin'");
Assert.True(result);
var result1 = scriptingEngine.Evaluate(scriptingScope, "var user2 = getUserByName('admin'); return user2.userName");
Assert.NotNull(result1);
});
}
}
Loading