From db7fd5e8461c49671ebbecf8637442fa4f9181b4 Mon Sep 17 00:00:00 2001 From: Michael Becker Date: Mon, 13 Jan 2025 16:50:28 -0500 Subject: [PATCH] improve some stuff and rearrange other stuff --- .dockerignore | 6 ++ Dockerfile | 10 +++ mocha-common | 2 +- mocha-dotnet.sln | 7 ++ .../src/app/Mocha.Oms.Server/Program.cs | 2 +- .../Commands/ElementCommand.cs | 49 +++++++----- .../src/lib/Mocha.Core/KnownInstanceGuids.cs | 1 + .../lib/Mocha.Core/KnownRelationshipGuids.cs | 2 + mocha-dotnet/src/lib/Mocha.Core/Oms.cs | 33 ++++++-- mocha-dotnet/src/lib/Mocha.Core/OmsContext.cs | 3 + .../src/lib/Mocha.Core/UI/Renderer.cs | 6 ++ mocha-dotnet/src/lib/Mocha.Core/UI/Widget.cs | 29 +++++-- .../Mocha.Core/UI/Widgets/CommandButton.cs | 29 +++++++ .../src/lib/Mocha.Core/UI/Widgets/Element.cs | 16 +++- .../lib/Mocha.Core/UI/Widgets/MonikerList.cs | 2 +- .../lib/Mocha.Testing}/EmbeddedMiniOms.cs | 28 +++++-- .../lib/Mocha.Testing/Mocha.Testing.csproj | 25 ++++++ .../lib/Mocha.Testing}/OmsTestsBase.cs | 27 +++++-- .../Resources/net.alcetech.Mocha.System.mcl | 1 + .../Resources/net.alcetech.Mocha.Web.mcl | 1 + .../tests/Mocha.Core.Tests/BasicTests.cs | 5 +- .../Mocha.Core.Tests/DerivedInstanceTests.cs | 1 + .../Mocha.Core.Tests/InheritanceTests.cs | 4 +- .../Mocha.Core.Tests/LibraryLoaderTests.cs | 6 +- .../tests/Mocha.Core.Tests/MethodTestsBase.cs | 1 + .../Mocha.Core.Tests/Mocha.Core.Tests.csproj | 6 +- .../Modeling/OmsModelingTestsBase.cs | 1 + .../tests/Mocha.Core.Tests/ModuleTests.cs | 1 + .../Oop/AccessModifierTests.cs | 1 + .../Mocha.Core.Tests/RelationshipTests.cs | 1 + .../Resources/net.alcetech.Mocha.System.mcl | 1 - .../Resources/net.alcetech.Mocha.Web.mcl | 1 - .../SampleDatabases/MovieRentalTests.cs | 1 + .../tests/Mocha.Core.Tests/TenantedTests.cs | 80 +++++++++++++++++++ .../tests/Mocha.Core.Tests/UI/UITests.cs | 1 + .../tests/Mocha.Core.Tests/WorkSetTests.cs | 1 + .../Mocha.Oms.Server.Tests/LocalTests.cs | 43 ++++++++++ .../{BasicTests.cs => RemoteTests.cs} | 25 +++++- 38 files changed, 395 insertions(+), 64 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/CommandButton.cs rename mocha-dotnet/{tests/Mocha.Core.Tests => src/lib/Mocha.Testing}/EmbeddedMiniOms.cs (50%) create mode 100644 mocha-dotnet/src/lib/Mocha.Testing/Mocha.Testing.csproj rename mocha-dotnet/{tests/Mocha.Core.Tests => src/lib/Mocha.Testing}/OmsTestsBase.cs (91%) create mode 120000 mocha-dotnet/src/lib/Mocha.Testing/Resources/net.alcetech.Mocha.System.mcl create mode 120000 mocha-dotnet/src/lib/Mocha.Testing/Resources/net.alcetech.Mocha.Web.mcl delete mode 120000 mocha-dotnet/tests/Mocha.Core.Tests/Resources/net.alcetech.Mocha.System.mcl delete mode 120000 mocha-dotnet/tests/Mocha.Core.Tests/Resources/net.alcetech.Mocha.Web.mcl create mode 100644 mocha-dotnet/tests/Mocha.Core.Tests/TenantedTests.cs create mode 100644 mocha-dotnet/tests/Mocha.Oms.Server.Tests/LocalTests.cs rename mocha-dotnet/tests/Mocha.Oms.Server.Tests/{BasicTests.cs => RemoteTests.cs} (84%) diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..9d414d4 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +/node_modules +/dist +.gitignore +.gitattributes +LICENSE +README.md \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..42dc662 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,10 @@ +FROM node:16-alpine +WORKDIR /usr/src/app +COPY package*.json ./ +RUN npm i +COPY . . +RUN npm install -g @angular/cli +RUN ng build +RUN npm i -g serve +EXPOSE 3000 +CMD [ "serve", "-S" , "dist/my-app-angular"] diff --git a/mocha-common b/mocha-common index 5a4d4aa..d6bc710 160000 --- a/mocha-common +++ b/mocha-common @@ -1 +1 @@ -Subproject commit 5a4d4aa243bc02348eb717496739c696268a3a1e +Subproject commit d6bc710f327d3c45361063ab6cf3201e0531d4d9 diff --git a/mocha-dotnet.sln b/mocha-dotnet.sln index 0564e7d..1923f04 100644 --- a/mocha-dotnet.sln +++ b/mocha-dotnet.sln @@ -53,6 +53,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mocha.Zq.Integration", "moc EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mocha.Oms.Server.Tests", "mocha-dotnet\tests\Mocha.Oms.Server.Tests\Mocha.Oms.Server.Tests.csproj", "{271CBF6A-07E4-46EB-A418-513E9FD89E36}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mocha.Testing", "mocha-dotnet\src\lib\Mocha.Testing\Mocha.Testing.csproj", "{5DE4A4AF-9B11-4844-B9C3-D93E17536267}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -107,6 +109,10 @@ Global {271CBF6A-07E4-46EB-A418-513E9FD89E36}.Debug|Any CPU.Build.0 = Debug|Any CPU {271CBF6A-07E4-46EB-A418-513E9FD89E36}.Release|Any CPU.ActiveCfg = Release|Any CPU {271CBF6A-07E4-46EB-A418-513E9FD89E36}.Release|Any CPU.Build.0 = Release|Any CPU + {5DE4A4AF-9B11-4844-B9C3-D93E17536267}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5DE4A4AF-9B11-4844-B9C3-D93E17536267}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5DE4A4AF-9B11-4844-B9C3-D93E17536267}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5DE4A4AF-9B11-4844-B9C3-D93E17536267}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -134,6 +140,7 @@ Global {F5D1EF0F-B42F-4237-B08A-7A78143C3ECB} = {27C300F5-5172-4225-A6F7-3503B9007DD8} {ADD7359E-0E3B-4435-B812-EC961C52DA2A} = {A2C401E9-FED4-43BA-A928-566239894CEE} {271CBF6A-07E4-46EB-A418-513E9FD89E36} = {27C300F5-5172-4225-A6F7-3503B9007DD8} + {5DE4A4AF-9B11-4844-B9C3-D93E17536267} = {A2C401E9-FED4-43BA-A928-566239894CEE} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D28A9CF8-0235-4F8F-865F-C460BDCAE16D} diff --git a/mocha-dotnet/src/app/Mocha.Oms.Server/Program.cs b/mocha-dotnet/src/app/Mocha.Oms.Server/Program.cs index aa870db..087a243 100644 --- a/mocha-dotnet/src/app/Mocha.Oms.Server/Program.cs +++ b/mocha-dotnet/src/app/Mocha.Oms.Server/Program.cs @@ -156,7 +156,7 @@ public class Program : WebApplication base.OnProcessRequest(e); OmsContext ctx = null; - if (!e.Context.Session.ContainsKey("OmsContext")) + if (!e.Context.Session.ContainsKey("OmsContext")) { ctx = Oms.CreateContext(); e.Context.Session["OmsContext"] = ctx; diff --git a/mocha-dotnet/src/lib/Mocha.Core.UI.Server/Commands/ElementCommand.cs b/mocha-dotnet/src/lib/Mocha.Core.UI.Server/Commands/ElementCommand.cs index 9f89b65..b48e047 100644 --- a/mocha-dotnet/src/lib/Mocha.Core.UI.Server/Commands/ElementCommand.cs +++ b/mocha-dotnet/src/lib/Mocha.Core.UI.Server/Commands/ElementCommand.cs @@ -34,6 +34,8 @@ public class ElementCommand : InstanceCommand { if (oms.IsInstanceOf(ProcessingInstance, oms.GetInstance(KnownInstanceGuids.Classes.Element))) { + ctx.SetWorkData(oms.GetInstance(KnownInstanceGuids.Classes.Instance), ProcessingInstance); + // what we should do, is build a transaction with all updated ECs and fields and values // if any update fails, the entire transaction should be rolled back Response resp = oms.ProcessElement(ctx, ProcessingInstance, e.Context.Request.Form); @@ -82,6 +84,13 @@ public class ElementCommand : InstanceCommand label = oms.GetInstanceText(widget.ParentInstance); } objTitle.Add("label", label); + + IEnumerable defaultDisplayOptions = oms.GetRelatedInstances(widget.ParentInstance, oms.GetInstance(KnownRelationshipGuids.Element__has_default__Display_Option)); + if (defaultDisplayOptions.Contains(oms.GetInstance(KnownInstanceGuids.ElementContentDisplayOptions.DoNotShowLabel))) + { + objTitle.Add("visible", false); + } + // objTitle.Add("src", "ElementCommand"); obj2.Add("title", objTitle); JsonObject obj = new JsonObject(); @@ -91,17 +100,7 @@ public class ElementCommand : InstanceCommand } else if (oms.IsInstanceOf(ProcessingInstance, oms.GetInstance(KnownInstanceGuids.Classes.Task))) { - InstanceHandle elem = oms.GetRelatedInstance(ProcessingInstance, oms.GetInstance(KnownRelationshipGuids.Task__has_initiating__Element)); - - // fill out the initiating element and execute the task - Response r = oms.ProcessElement(ctx, elem, null); - JsonObject obj = r.GetResponse(oms, ctx); - - /* - - */ - - RespondWithJson(oms, sw, e.Context, 200, "OK", obj); + RespndWithTask(oms, sw, e.Context, ctx, ProcessingInstance); } else { @@ -111,19 +110,25 @@ public class ElementCommand : InstanceCommand InstanceHandle defaultTask = oms.GetRelatedInstance(parentClass, oms.GetInstance(KnownRelationshipGuids.Class__has_default__Task)); if (defaultTask != InstanceHandle.Empty) { - InstanceHandle elem = oms.GetRelatedInstance(defaultTask, oms.GetInstance(KnownRelationshipGuids.Task__has_initiating__Element)); - - // fill out the initiating element and execute the task - Response r = oms.ProcessElement(ctx, elem, null); - JsonObject obj = r.GetResponse(oms, ctx); - - /* - - */ - - RespondWithJson(oms, sw, e.Context, 200, "OK", obj); + RespndWithTask(oms, sw, e.Context, ctx, defaultTask); } } } } + + private void RespndWithTask(Oms oms, StreamWriter sw, WebContext context, OmsContext omsContext, InstanceHandle task) + { + // fill out the initiating element and execute the task + InstanceHandle elem = oms.GetRelatedInstance(task, oms.GetInstance(KnownRelationshipGuids.Task__has_initiating__Element)); + omsContext.InitiatingTask = task; + + Response r = oms.ProcessElement(omsContext, elem, null); + JsonObject obj = r.GetResponse(oms, omsContext); + + /* + + */ + + RespondWithJson(oms, sw, context, 200, "OK", obj); + } } \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Core/KnownInstanceGuids.cs b/mocha-dotnet/src/lib/Mocha.Core/KnownInstanceGuids.cs index 07c17ab..15a61da 100755 --- a/mocha-dotnet/src/lib/Mocha.Core/KnownInstanceGuids.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/KnownInstanceGuids.cs @@ -129,6 +129,7 @@ namespace Mocha.Core public static Guid GroupLayout { get; } = new Guid("{108605af-c20d-42eb-af4f-35b2ff701921}"); public static Guid ImageLayout { get; } = new Guid("{4b1bb7c6-168e-4ce0-b4f8-76dd5069a80b}"); + public static Guid ButtonLayout { get; } = new Guid("{6f6338db-68e0-4cc7-b257-d1b97cf3cb92}"); public static Guid Menu { get; } = new Guid("{c952ef83-af18-4512-9dd9-0f00a19d399c}"); public static Guid MenuItem { get; } = new Guid("{f606f612-2d12-4600-bee1-a071d1019ffe}"); diff --git a/mocha-dotnet/src/lib/Mocha.Core/KnownRelationshipGuids.cs b/mocha-dotnet/src/lib/Mocha.Core/KnownRelationshipGuids.cs index 19c8738..cd7810c 100755 --- a/mocha-dotnet/src/lib/Mocha.Core/KnownRelationshipGuids.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/KnownRelationshipGuids.cs @@ -318,6 +318,8 @@ namespace Mocha.Core public static Guid Element__has__Element_Content { get; } = new Guid("{c1d32481-02f9-48c6-baf8-37d93fa8da23}"); public static Guid Element_Content__for__Element { get; } = new Guid("{2eff7f58-0edd-40b7-9c06-00774257649e}"); + public static Guid Element__has_default__Display_Option { get; } = new Guid("{2ffeb5be-98fe-4008-a4d3-fd5b31ad320a}"); + public static Guid Element__has_label__Translation { get; } = new Guid("{7147ea90-9f45-4bb9-b151-025b6e2bd834}"); public static Guid Element_Content__has__Instance { get; } = new Guid("{315b71ba-953d-45fc-87e5-4f0a268242a9}"); diff --git a/mocha-dotnet/src/lib/Mocha.Core/Oms.cs b/mocha-dotnet/src/lib/Mocha.Core/Oms.cs index 3156c1d..8668733 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/Oms.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/Oms.cs @@ -651,20 +651,20 @@ public abstract class Oms } private Dictionary?> _derivedData = new Dictionary?>(); - public Dictionary? GetDerivedData(InstanceHandle source) + public Dictionary? GetDerivedData(IInstanceReference source) { if (IsDerivedInstance(source)) { - if (!_derivedData.ContainsKey(source)) + if (!_derivedData.ContainsKey(source.GetHandle())) { - _derivedData[source] = new Dictionary(); + _derivedData[source.GetHandle()] = new Dictionary(); } - return _derivedData[source]; + return _derivedData[source.GetHandle()]; } return null; } - public bool IsDerivedInstance(InstanceHandle source) + public bool IsDerivedInstance(IInstanceReference source) { // !!! we cannot use GetAttributeValue here !!! InstanceHandle pclass = GetParentClass(source); @@ -694,7 +694,7 @@ public abstract class Oms return GetAttributeValue(hSource, attribute, defaultValue, effectiveDate); } } - public T GetAttributeValue(InstanceHandle source, InstanceHandle attribute, T defaultValue = default(T), DateTime? effectiveDate = null) + public T GetAttributeValue(IInstanceReference source, InstanceHandle attribute, T defaultValue = default(T), DateTime? effectiveDate = null) { Dictionary? derivedData = GetDerivedData(source); if (derivedData != null) @@ -2099,6 +2099,7 @@ public abstract class Oms else { Renderer renderer = new Renderer(this); + string title = GetLabelForUIElement(element); Widget widget = renderer.Parse(ctx, element, InstanceHandle.Empty, InstanceHandle.Empty); if (widget == null) { @@ -2112,6 +2113,16 @@ public abstract class Oms JsonObject obj2 = new JsonObject(); obj2.Add("widget", JsonValue.Create("root")); obj2.Add("body", widget.ToJSONObject(ctx)); + + JsonObject objTitle = new JsonObject(); + // hack + if (String.IsNullOrEmpty(title) && ctx.InitiatingTask != InstanceHandle.Empty) + { + title = oms.GetInstanceText(ctx.InitiatingTask); + } + objTitle.Add("label", title); + // objTitle.Add("src", "Oms"); + obj2.Add("title", objTitle); JsonObject obj = new JsonObject(); obj.Add("result", "success"); @@ -2210,4 +2221,14 @@ public abstract class Oms } return InstanceHandle.Empty; } + + private Stack _tenantStack = new Stack(); + public void PushTenant(TenantHandle tenant) + { + _tenantStack.Push(tenant); + } + public TenantHandle PopTenant() + { + return _tenantStack.Pop(); + } } diff --git a/mocha-dotnet/src/lib/Mocha.Core/OmsContext.cs b/mocha-dotnet/src/lib/Mocha.Core/OmsContext.cs index ff0a548..42df2ff 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/OmsContext.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/OmsContext.cs @@ -28,6 +28,9 @@ public class OmsContext private Stack TargetInstances = new Stack(); private Stack> WorkDataSets = new Stack>(); + public InstanceHandle? InitiatingTask { get; set; } + + public IInstanceReference? TargetInstance { get diff --git a/mocha-dotnet/src/lib/Mocha.Core/UI/Renderer.cs b/mocha-dotnet/src/lib/Mocha.Core/UI/Renderer.cs index ed8fca8..420cea5 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/UI/Renderer.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/UI/Renderer.cs @@ -16,6 +16,7 @@ // along with Mocha.NET. If not, see . using System.Text.Json.Nodes; +using Mocha.Core.UI.Widgets; namespace Mocha.Core.UI; @@ -72,6 +73,11 @@ public class Renderer break; } + if (OMS.IsInstanceOf(layoutInstance, OMS.GetInstance(KnownInstanceGuids.Classes.ButtonLayout))) + { + useWidget = new CommandButton(); + } + if (useWidget == null) { Console.Error.WriteLine("not found widget for GID " + gid.ToString()); diff --git a/mocha-dotnet/src/lib/Mocha.Core/UI/Widget.cs b/mocha-dotnet/src/lib/Mocha.Core/UI/Widget.cs index 04b1274..69fd21a 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/UI/Widget.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/UI/Widget.cs @@ -67,19 +67,34 @@ public abstract class Widget { obj.Add("widget", GetWidgetName()); obj.Add("iid", JsonValue.Create(OMS.GetInstanceKey(ParentInstance).ToString())); + + bool showLabel = true; + showLabel = !OMS.IsInstanceOf(ParentInstance, OMS.GetInstance(KnownInstanceGuids.Classes.Element)); + if (ParentElementContent != InstanceHandle.Empty) { - IEnumerable displayOptions = GetDisplayOptions(); - obj.Add("ecid", JsonValue.Create(OMS.GetInstanceKey(ParentElementContent).ToString())); - - if (!displayOptions.Contains(OMS.GetInstance(KnownInstanceGuids.ElementContentDisplayOptions.DoNotShowLabel))) + /* + InstanceHandle layout = OMS.GetRelatedInstance(ParentElementContent, OMS.GetInstance(KnownRelationshipGuids.Element_Content__has__Layout)); + if (OMS.IsInstanceOf(layout, OMS.GetInstance(KnownInstanceGuids.Classes.GroupLayout))) { - if (!OMS.IsInstanceOf(ParentInstance, OMS.GetInstance(KnownInstanceGuids.Classes.Element))) + IEnumerable groupLayoutOptions = OMS.GetRelatedInstances(layout, OMS.GetInstance(KnownRelationshipGuids.Group_Layout__uses__Group_Layout_Option)); + if (groupLayoutOptions.Contains(OMS.GetInstance(KnownInstanceGuids.GroupLayoutOptions.Tabbed))) { - string label = OMS.GetLabelForUIElement(ParentElementContent); - obj.Add("label", label); + showLabel |= true; } } + */ + IEnumerable displayOptions = GetDisplayOptions(); + showLabel &= !displayOptions.Contains(OMS.GetInstance(KnownInstanceGuids.ElementContentDisplayOptions.DoNotShowLabel)); + + obj.Add("ecid", JsonValue.Create(OMS.GetInstanceKey(ParentElementContent).ToString())); + + if (showLabel) + { + string label = OMS.GetLabelForUIElement(ParentElementContent); + obj.Add("label", label); + } + if (!ShouldBeEnabled()) { obj.Add("enabled", false); diff --git a/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/CommandButton.cs b/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/CommandButton.cs new file mode 100644 index 0000000..7461e16 --- /dev/null +++ b/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/CommandButton.cs @@ -0,0 +1,29 @@ +// Copyright (C) 2025 Michael Becker +// +// This file is part of Mocha.NET. +// +// Mocha.NET is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Mocha.NET is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Mocha.NET. If not, see . + +using System.Text.Json.Nodes; + +namespace Mocha.Core.UI.Widgets; + +public class CommandButton : Widget +{ + protected override string GetWidgetName() => "commandButton"; + + protected override void RenderJSONInternal(OmsContext context, JsonObject obj) + { + } +} \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/Element.cs b/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/Element.cs index e8cd10b..4d7eeeb 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/Element.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/Element.cs @@ -65,12 +65,21 @@ public class Element : Widget if (OMS.IsInstanceOf(layout, OMS.GetInstance(KnownInstanceGuids.Classes.GroupLayout))) { + InstanceHandle ihGLOTabbed = OMS.GetInstance(KnownInstanceGuids.GroupLayoutOptions.Tabbed); InstanceHandle ihGLOFieldSet = OMS.GetInstance(KnownInstanceGuids.GroupLayoutOptions.FieldSet); IEnumerable groupLayoutOptions = OMS.GetRelatedInstances(layout, OMS.GetInstance(KnownRelationshipGuids.Group_Layout__uses__Group_Layout_Option)); if (groupLayoutOptions.Contains(ihGLOFieldSet)) { return "fieldSet"; } + else if (groupLayoutOptions.Contains(ihGLOTabbed)) + { + return "tabContainer"; + } + } + else if (OMS.IsInstanceOf(layout, OMS.GetInstance(KnownInstanceGuids.Classes.ButtonLayout))) + { + return "commandButton"; } return "vbox"; } @@ -149,7 +158,12 @@ public class Element : Widget } else { - objA.Add(widget.ToJSONObject(context)); + JsonObject obj1 = widget.ToJSONObject(context); + if (this.GetWidgetName().Equals("tabContainer")) + { + obj1.Add("label", OMS.GetLabelForUIElement(content)); + } + objA.Add(obj1); } } diff --git a/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/MonikerList.cs b/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/MonikerList.cs index 155bfe2..c938dee 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/MonikerList.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/MonikerList.cs @@ -22,7 +22,7 @@ namespace Mocha.Core.UI; public class MonikerList : Widget { protected override string GetWidgetName() => "monikerList"; - public override Guid[] SupportedClassGuids => new Guid[] { KnownInstanceGuids.Classes.WorkSet, KnownInstanceGuids.Classes.Class, KnownInstanceGuids.Classes.ReturnInstanceSetMethodBinding }; + public override Guid[] SupportedClassGuids => new Guid[] { KnownInstanceGuids.Classes.WorkSet, KnownInstanceGuids.Classes.Class, KnownInstanceGuids.Classes.ReturnInstanceSetMethodBinding, KnownInstanceGuids.Classes.Relationship }; public List SelectedInstances { get; } = new List(); diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/EmbeddedMiniOms.cs b/mocha-dotnet/src/lib/Mocha.Testing/EmbeddedMiniOms.cs similarity index 50% rename from mocha-dotnet/tests/Mocha.Core.Tests/EmbeddedMiniOms.cs rename to mocha-dotnet/src/lib/Mocha.Testing/EmbeddedMiniOms.cs index a53d050..6bce379 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/EmbeddedMiniOms.cs +++ b/mocha-dotnet/src/lib/Mocha.Testing/EmbeddedMiniOms.cs @@ -1,21 +1,37 @@ +using System; +using Mocha.Core; using Mocha.Core.OmsImplementations; -namespace Mocha.Core.Tests; +namespace Mocha.Testing; public class EmbeddedMiniOms : MemoryOms { - public string? SystemLibraryResourceName { get; set; } = "Mocha.Core.Tests.Resources.net.alcetech.Mocha.System.mcl"; + public string? SystemLibraryResourceName { get; set; } = "Mocha.Testing.Resources.net.alcetech.Mocha.System.mcl"; - protected override void InitializeInternal() + protected override void OnTenantCreated(OmsTenantCreatedEventArgs e) { - base.InitializeInternal(); + TenantHandle h = CurrentTenant; - TenantHandle th = CreateTenant("super"); - SelectTenant(th); + SelectTenant(e.Tenant); if (SystemLibraryResourceName != null) { LibraryHandle lh = LoadLibrary(typeof(EmbeddedMiniOms), SystemLibraryResourceName); AddLibraryReference(lh); } + ReleaseTenant(); + + if (h != TenantHandle.Empty) + { + SelectTenant(h); + } + + base.OnTenantCreated(e); + } + + protected override void InitializeInternal() + { + base.InitializeInternal(); + + CreateTenant("super"); } } \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Testing/Mocha.Testing.csproj b/mocha-dotnet/src/lib/Mocha.Testing/Mocha.Testing.csproj new file mode 100644 index 0000000..1f9d724 --- /dev/null +++ b/mocha-dotnet/src/lib/Mocha.Testing/Mocha.Testing.csproj @@ -0,0 +1,25 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + + + + + + + diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/OmsTestsBase.cs b/mocha-dotnet/src/lib/Mocha.Testing/OmsTestsBase.cs similarity index 91% rename from mocha-dotnet/tests/Mocha.Core.Tests/OmsTestsBase.cs rename to mocha-dotnet/src/lib/Mocha.Testing/OmsTestsBase.cs index a84d265..3591714 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/OmsTestsBase.cs +++ b/mocha-dotnet/src/lib/Mocha.Testing/OmsTestsBase.cs @@ -1,4 +1,4 @@ -// Copyright (C) 2024 Michael Becker +// Copyright (C) 2024 Michael Becker // // This file is part of Mocha.NET. // @@ -15,21 +15,36 @@ // You should have received a copy of the GNU General Public License // along with Mocha.NET. If not, see . +using Mocha.Core; +using Mocha.Core.OmsImplementations; using Mocha.Core.Oop; +using NUnit.Framework; -namespace Mocha.Core.Tests; +namespace Mocha.Testing; public abstract class OmsTestsBase { public Oms Oms { get; private set; } + protected string GetEmbeddedResourceName(string name) + { + return "Mocha.Testing.Resources." + name; + } + protected Oms CreateOms() { - EmbeddedMiniOms oms = new EmbeddedMiniOms(); - oms.Initialize(); + Oms oms = new EmbeddedMiniOms(); + oms.TenantCreated += delegate (object sender, OmsTenantCreatedEventArgs e) + { + oms.PushTenant(e.Tenant); - oms.CreateClass("Test Class", TEST_CLASS_GUID); - oms.CreateClass("Test Class 2", TEST_CLASS2_GUID); + oms.CreateClass("Test Class", TEST_CLASS_GUID); + oms.CreateClass("Test Class 2", TEST_CLASS2_GUID); + + oms.PopTenant(); + }; + + oms.Initialize(); return oms; } diff --git a/mocha-dotnet/src/lib/Mocha.Testing/Resources/net.alcetech.Mocha.System.mcl b/mocha-dotnet/src/lib/Mocha.Testing/Resources/net.alcetech.Mocha.System.mcl new file mode 120000 index 0000000..2768e4b --- /dev/null +++ b/mocha-dotnet/src/lib/Mocha.Testing/Resources/net.alcetech.Mocha.System.mcl @@ -0,0 +1 @@ +../../../../../mocha-common/mocha-common/output/net.alcetech.Mocha.System.mcl \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Testing/Resources/net.alcetech.Mocha.Web.mcl b/mocha-dotnet/src/lib/Mocha.Testing/Resources/net.alcetech.Mocha.Web.mcl new file mode 120000 index 0000000..f73b376 --- /dev/null +++ b/mocha-dotnet/src/lib/Mocha.Testing/Resources/net.alcetech.Mocha.Web.mcl @@ -0,0 +1 @@ +../../../../../mocha-common/mocha-common/output/net.alcetech.Mocha.Web.mcl \ No newline at end of file diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/BasicTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/BasicTests.cs index 1d30262..4c1511a 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/BasicTests.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/BasicTests.cs @@ -18,6 +18,7 @@ using System.Runtime.CompilerServices; using MBS.Core.Collections; using Mocha.Core.Oop; +using Mocha.Testing; namespace Mocha.Core.Tests; @@ -141,7 +142,7 @@ public class BasicTests : OmsTestsBase InstanceHandle ihTextAttribute = Oms.GetInstance(KnownInstanceGuids.Classes.TextAttribute); // load the other library, but do not reference it yet - LibraryHandle lhWeb = Oms.LoadLibrary(typeof(LibraryLoaderTests), "Mocha.Core.Tests.Resources.net.alcetech.Mocha.Web.mcl"); + LibraryHandle lhWeb = Oms.LoadLibrary(typeof(OmsTestsBase), GetEmbeddedResourceName("net.alcetech.Mocha.Web.mcl")); // add back the reference to the other library // Oms.AddLibraryReference(lhWeb); @@ -159,7 +160,7 @@ public class BasicTests : OmsTestsBase InstanceHandle ihTextAttribute = Oms.GetInstance(KnownInstanceGuids.Classes.Class); // load the other library, but do not reference it yet - LibraryHandle lhWeb = Oms.LoadLibrary(typeof(LibraryLoaderTests), "Mocha.Core.Tests.Resources.net.alcetech.Mocha.Web.mcl"); + LibraryHandle lhWeb = Oms.LoadLibrary(typeof(OmsTestsBase), GetEmbeddedResourceName("net.alcetech.Mocha.Web.mcl")); // add back the reference to the other library Oms.AddLibraryReference(lhWeb); diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/DerivedInstanceTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/DerivedInstanceTests.cs index a07810b..a7782e6 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/DerivedInstanceTests.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/DerivedInstanceTests.cs @@ -1,5 +1,6 @@ using System; using Mocha.Core.Oop; +using Mocha.Testing; using Newtonsoft.Json.Serialization; namespace Mocha.Core.Tests; diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/InheritanceTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/InheritanceTests.cs index 6d6741f..c8f99cc 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/InheritanceTests.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/InheritanceTests.cs @@ -15,6 +15,8 @@ // You should have received a copy of the GNU General Public License // along with Mocha.NET. If not, see . +using Mocha.Testing; + namespace Mocha.Core.Tests; [TestFixture] @@ -34,7 +36,7 @@ public class InheritanceTests : OmsTestsBase public void TextAttribute_ParentClass_is_Class_when_multiple_libraries_are_referenced() { // add a reference to the other library - LibraryHandle lhWeb = Oms.LoadLibrary(typeof(LibraryLoaderTests), "Mocha.Core.Tests.Resources.net.alcetech.Mocha.Web.mcl"); + LibraryHandle lhWeb = Oms.LoadLibrary(typeof(OmsTestsBase), GetEmbeddedResourceName("net.alcetech.Mocha.Web.mcl")); Oms.AddLibraryReference(lhWeb); // ??? this is weird. the moment we add that library reference, this suddenly breaks diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/LibraryLoaderTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/LibraryLoaderTests.cs index b66e1c0..868557f 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/LibraryLoaderTests.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/LibraryLoaderTests.cs @@ -15,6 +15,8 @@ // You should have received a copy of the GNU General Public License // along with Mocha.NET. If not, see . +using Mocha.Testing; + namespace Mocha.Core.Tests; [TestFixture] @@ -27,9 +29,9 @@ public class LibraryLoaderTests : OmsTestsBase base.AfterSetup(); // add a reference to the other library - LibraryHandle lhSystem = Oms.GetLibrary("Mocha.Core.Tests.Resources.net.alcetech.Mocha.System.mcl"); + LibraryHandle lhSystem = Oms.GetLibrary(GetEmbeddedResourceName("net.alcetech.Mocha.System.mcl")); - lhWeb = Oms.LoadLibrary(typeof(LibraryLoaderTests), "Mocha.Core.Tests.Resources.net.alcetech.Mocha.Web.mcl"); + lhWeb = Oms.LoadLibrary(typeof(OmsTestsBase), GetEmbeddedResourceName("net.alcetech.Mocha.Web.mcl")); Oms.AddLibraryReference(lhWeb); } diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/MethodTestsBase.cs b/mocha-dotnet/tests/Mocha.Core.Tests/MethodTestsBase.cs index 37911fc..e98fdb1 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/MethodTestsBase.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/MethodTestsBase.cs @@ -16,6 +16,7 @@ // along with Mocha.NET. If not, see . using Mocha.Core.Oop; +using Mocha.Testing; namespace Mocha.Core.Tests; diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/Mocha.Core.Tests.csproj b/mocha-dotnet/tests/Mocha.Core.Tests/Mocha.Core.Tests.csproj index c4cedfd..5288e2d 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/Mocha.Core.Tests.csproj +++ b/mocha-dotnet/tests/Mocha.Core.Tests/Mocha.Core.Tests.csproj @@ -37,14 +37,10 @@ + - - - - - diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/Modeling/OmsModelingTestsBase.cs b/mocha-dotnet/tests/Mocha.Core.Tests/Modeling/OmsModelingTestsBase.cs index b6e6edd..6f7ce8d 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/Modeling/OmsModelingTestsBase.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/Modeling/OmsModelingTestsBase.cs @@ -16,6 +16,7 @@ // along with Mocha.NET. If not, see . using Mocha.Core.Modeling; +using Mocha.Testing; namespace Mocha.Core.Tests.Modeling; diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/ModuleTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/ModuleTests.cs index 9317c35..6248668 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/ModuleTests.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/ModuleTests.cs @@ -1,5 +1,6 @@ using System; using Mocha.Core.Oop; +using Mocha.Testing; namespace Mocha.Core.Tests; diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/Oop/AccessModifierTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/Oop/AccessModifierTests.cs index e008ca6..913ee70 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/Oop/AccessModifierTests.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/Oop/AccessModifierTests.cs @@ -1,6 +1,7 @@ using System; using Mocha.Core.Oop; using Mocha.Core.Oop.Methods; +using Mocha.Testing; namespace Mocha.Core.Tests.Oop; diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/RelationshipTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/RelationshipTests.cs index 4b08758..6f995c0 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/RelationshipTests.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/RelationshipTests.cs @@ -17,6 +17,7 @@ using Mocha.Core.Oop; +using Mocha.Testing; namespace Mocha.Core.Tests; diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/Resources/net.alcetech.Mocha.System.mcl b/mocha-dotnet/tests/Mocha.Core.Tests/Resources/net.alcetech.Mocha.System.mcl deleted file mode 120000 index 16ed5d0..0000000 --- a/mocha-dotnet/tests/Mocha.Core.Tests/Resources/net.alcetech.Mocha.System.mcl +++ /dev/null @@ -1 +0,0 @@ -../../../../mocha-common/mocha-common/output/net.alcetech.Mocha.System.mcl \ No newline at end of file diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/Resources/net.alcetech.Mocha.Web.mcl b/mocha-dotnet/tests/Mocha.Core.Tests/Resources/net.alcetech.Mocha.Web.mcl deleted file mode 120000 index ac4f683..0000000 --- a/mocha-dotnet/tests/Mocha.Core.Tests/Resources/net.alcetech.Mocha.Web.mcl +++ /dev/null @@ -1 +0,0 @@ -../../../../mocha-common/mocha-common/output/net.alcetech.Mocha.Web.mcl \ No newline at end of file diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/SampleDatabases/MovieRentalTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/SampleDatabases/MovieRentalTests.cs index 78a4253..7e0daef 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/SampleDatabases/MovieRentalTests.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/SampleDatabases/MovieRentalTests.cs @@ -17,6 +17,7 @@ using Mocha.Core.Oop; +using Mocha.Testing; namespace Mocha.Core.Tests.SampleDatabases; diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/TenantedTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/TenantedTests.cs new file mode 100644 index 0000000..ea038d8 --- /dev/null +++ b/mocha-dotnet/tests/Mocha.Core.Tests/TenantedTests.cs @@ -0,0 +1,80 @@ +// Copyright (C) 2025 Michael Becker +// +// This file is part of Mocha.NET. +// +// Mocha.NET is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Mocha.NET is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Mocha.NET. If not, see . + +using Mocha.Core; +using Mocha.Core.Oop; +using Mocha.Core.Tests; +using Mocha.Testing; + +namespace Mocha.Core.Tests; + +public class TenantedTests : OmsTestsBase +{ + protected override void AfterSetup() + { + base.AfterSetup(); + + Oms.CreateTenant("omstest"); + } + + [Test] + public void Create_Class_On_First_Tenant_Doesnt_Show_Up_On_Second_Tenant() + { + Oms.SelectTenant(Oms.GetTenantByName("super")); + + Guid gid = new Guid("{0fcc3a69-79c8-4884-9bd4-269b7460314b}"); + Class cls = Oms.CreateClass("System Tenanted Test Class", gid); + + + Oms.SelectTenant(Oms.GetTenantByName("omstest")); + + bool k = Oms.TryGetInstance(gid, out Class cls2); + Assert.That(k, Is.EqualTo(false)); + Assert.That(cls2, Is.Null); + } + + [Test] + public void GetInstance_Between_Tenants_Returns_Different_InstanceHandle() + { + Oms.SelectTenant(Oms.GetTenantByName("super")); + + Class cls = Oms.GetInstance(TEST_CLASS_GUID); + + Oms.SelectTenant(Oms.GetTenantByName("omstest")); + + Class cls2 = Oms.GetInstance(TEST_CLASS_GUID); + + Assert.That(cls.GetHandle(), Is.Not.EqualTo(cls2.GetHandle())); + } + + [Test] + public void Set_Attribute_On_First_Tenant_Doesnt_Change_On_Second_Tenant() + { + Oms.SelectTenant(Oms.GetTenantByName("super")); + + Class cls = Oms.GetInstance(TEST_CLASS_GUID); + InstanceHandle att = Oms.GetInstance(KnownAttributeGuids.Text.ContentType); + Oms.SetAttributeValue(cls, att, "Test Value"); + + Oms.SelectTenant(Oms.GetTenantByName("omstest")); + + Class cls2 = Oms.GetInstance(TEST_CLASS_GUID); + string val = Oms.GetAttributeValue(cls, att); + InstanceHandle att2 = Oms.GetInstance(KnownAttributeGuids.Text.ContentType); + Assert.That(val, Is.Not.EqualTo("Test Value")); + } +} \ No newline at end of file diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/UI/UITests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/UI/UITests.cs index 83e5c01..d4b8b95 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/UI/UITests.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/UI/UITests.cs @@ -1,5 +1,6 @@ using System; using System.Text.Json.Nodes; +using Mocha.Testing; namespace Mocha.Core.Tests.UI; diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/WorkSetTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/WorkSetTests.cs index 7fff933..35f7a5a 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/WorkSetTests.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/WorkSetTests.cs @@ -17,6 +17,7 @@ using Mocha.Core.Oop; +using Mocha.Testing; namespace Mocha.Core.Tests; diff --git a/mocha-dotnet/tests/Mocha.Oms.Server.Tests/LocalTests.cs b/mocha-dotnet/tests/Mocha.Oms.Server.Tests/LocalTests.cs new file mode 100644 index 0000000..294efbc --- /dev/null +++ b/mocha-dotnet/tests/Mocha.Oms.Server.Tests/LocalTests.cs @@ -0,0 +1,43 @@ +// Copyright (C) 2025 Michael Becker +// +// This file is part of Mocha.NET. +// +// Mocha.NET is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Mocha.NET is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Mocha.NET. If not, see . + +using Mocha.Core; +using Mocha.Core.OmsImplementations; + +namespace Mocha.Oms.Server.Tests; + +public class LocalTests +{ + public Mocha.Core.Oms? Oms { get; private set; } + + [SetUp] + public void SetUp() + { + Oms = new EmbeddedMiniOms(); + } + + [Test] + public void TestInstanceTaskWithGAS_GetGlobalIdentifier() + { + OmsContext context = Oms.CreateContext(); + InstanceHandle ProcessingInstance = Oms.GetInstance(new InstanceKey(56, 51)); + context.SetWorkData(Oms.GetInstance(KnownInstanceGuids.Classes.Instance), ProcessingInstance); + + Dictionary form = new Dictionary(); + Response resp = Oms.ProcessElement(context, ProcessingInstance, form); + } +} \ No newline at end of file diff --git a/mocha-dotnet/tests/Mocha.Oms.Server.Tests/BasicTests.cs b/mocha-dotnet/tests/Mocha.Oms.Server.Tests/RemoteTests.cs similarity index 84% rename from mocha-dotnet/tests/Mocha.Oms.Server.Tests/BasicTests.cs rename to mocha-dotnet/tests/Mocha.Oms.Server.Tests/RemoteTests.cs index 12eabb1..9dac075 100644 --- a/mocha-dotnet/tests/Mocha.Oms.Server.Tests/BasicTests.cs +++ b/mocha-dotnet/tests/Mocha.Oms.Server.Tests/RemoteTests.cs @@ -8,7 +8,7 @@ using NUnit.Framework.Interfaces; namespace Mocha.Oms.Server.Tests; -public class Tests +public class RemoteTests { private Thread ServerThread; private Program program; @@ -124,6 +124,29 @@ public class Tests Assert.That(json["value"]["widget"].ToString(), Is.EqualTo("root")); } + [Test] + public async Task Instance_Task_Test_with_GAS_Get_Global_Identifier() + { + Assert.That(program, Is.Not.Null); + + InstanceHandle h = program.Oms.GetInstance(KnownInstanceGuids.Classes.Class); + InstanceKey k = program.Oms.GetInstanceKey(h); + Guid g = program.Oms.GetGlobalIdentifier(h); + string sz = program.Oms.GetInstanceText(h); + + HttpClient client = new HttpClient(); + HttpResponseMessage resp = client.Send(new HttpRequestMessage(HttpMethod.Get, BuildUrl("/tenants/super/instances/56$51/element"))); + + Assert.That(resp.StatusCode, Is.EqualTo(System.Net.HttpStatusCode.OK)); + Assert.That(resp.Content.Headers.ContentType.ToString(), Is.EqualTo("application/json")); + + string content = await resp.Content.ReadAsStringAsync(); + + JsonObject json = JsonNode.Parse(content) as JsonObject; + Assert.That(json["result"].ToString(), Is.EqualTo("success")); + Assert.That(json["value"]["widget"].ToString(), Is.EqualTo("root")); + } + [Test] public async Task Globals_Test_Get_Empty_Value() {