diff --git a/mocha-dotnet/src/app/Mocha.Oms.Server/Program.cs b/mocha-dotnet/src/app/Mocha.Oms.Server/Program.cs index 55c3161..4708264 100644 --- a/mocha-dotnet/src/app/Mocha.Oms.Server/Program.cs +++ b/mocha-dotnet/src/app/Mocha.Oms.Server/Program.cs @@ -54,6 +54,16 @@ public class Program : WebApplication protected override void OnStartup(EventArgs e) { + string pidfile = "/var/run/mocha/mocha-oms.pid"; + try + { + System.IO.File.WriteAllText(pidfile, System.Environment.ProcessId.ToString()); + } + catch (Exception ex) + { + Console.Error.WriteLine("oms: error: failed to write PID file; graceful control will be unavailable"); + } + // this all has to be done before the Web server is started... oms.Initialize(); @@ -93,6 +103,9 @@ public class Program : WebApplication if (e.SystemRoutine.GlobalIdentifier == KnownInstanceGuids.SystemUpdateRoutines.LoginUser) { string token = e.Context.GetWorkData(e.OMS.GetInstance(KnownAttributeGuids.Text.Token)); + if (token == null) + return; + _Sessions[token] = new OmsSession(); } } 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 ba9f7da..18e772a 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 @@ -36,7 +36,7 @@ public class ElementCommand : InstanceCommand { // 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 = ProcessElement(oms, ctx, ProcessingInstance, InstanceHandle.Empty, e.Context.Request.Form); + Response resp = oms.ProcessElement(ctx, ProcessingInstance, e.Context.Request.Form); if (resp != null) { JsonObject obj2 = resp.GetResponse(oms, ctx); @@ -85,7 +85,7 @@ public class ElementCommand : InstanceCommand 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, InstanceHandle.Empty); + Response r = oms.ProcessElement(ctx, elem, null); JsonObject obj = r.GetResponse(oms, ctx); /* @@ -105,7 +105,7 @@ public class ElementCommand : InstanceCommand 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, ProcessingInstance); + Response r = oms.ProcessElement(ctx, elem, null); JsonObject obj = r.GetResponse(oms, ctx); /* @@ -117,105 +117,4 @@ public class ElementCommand : InstanceCommand } } } - - private Response ProcessElement(Core.Oms oms, OmsContext ctx, InstanceHandle element, InstanceHandle elementContent, ReadOnlyDictionary form, string fqecidPrefix = "") - { - // first we process the related updates - InstanceHandle processedByPru = oms.GetRelatedInstance(element, oms.GetInstance(KnownRelationshipGuids.Element__processed_by__Process_Related_Updates_Method)); - if (processedByPru != InstanceHandle.Empty) - { - // this works... so far - oms.UpdateElementContents(ctx, element, form); - oms.Execute(ctx, processedByPru); - /* - $executesMethod = $oms->getRelatedInstance($usesBRMB, KnownRelationshipGuids::Method_Binding__executes__Method); - if ($executesMethod === null) - { - trigger_error("task_step: 1; uses BRMB " . $usesBRMB . "; executes method is null"); - } - $usesElement = $oms->getRelatedInstance($executesMethod, KnownRelationshipGuids::Build_UI_Response_Method__uses__Executable_returning_Element); - - $this->updateWorkDataWithElementContents($parentElementContents, $element); - - $usesElementContents = $oms->getRelatedInstances($usesElement, KnownRelationshipGuids::Element__has__Element_Content); - if (count($usesElementContents) > 0) - { - $ecInst0 = $oms->getRelatedInstance($usesElementContents[0], KnownRelationshipGuids::Element_Content__has__Instance); - $this->TargetInstance = $this->Context->getWorkData($ecInst0); - - $this->renderTaskStep2($parentElementContents, $usesElement); - } - exit(); - */ - } - - // ... then we process the element contents... - IEnumerable elementContents = oms.GetRelatedInstances(element, oms.GetInstance(KnownRelationshipGuids.Element__has__Element_Content)); - foreach (InstanceHandle elementContent2 in elementContents) - { - Response? resp = ProcessElementContent(oms, ctx, elementContent2, form, fqecidPrefix); - if (resp != null) - { - return resp; - } - } - - // ... finally we run the CT - Control Transaction Method to return the response - InstanceHandle processedByCt = oms.GetRelatedInstance(element, oms.GetInstance(KnownRelationshipGuids.Element__processed_by__Control_Transaction_Method)); - if (processedByCt != InstanceHandle.Empty) - { - string destinationURL = oms.GetAttributeValue(processedByCt, oms.GetInstance(KnownAttributeGuids.Text.TargetURL)); - InstanceHandle usesBuildResponseMethodBinding = oms.GetRelatedInstance(processedByCt, oms.GetInstance(KnownRelationshipGuids.Control_Transaction_Method__uses__Build_Response_Method_Binding)); - if (usesBuildResponseMethodBinding != InstanceHandle.Empty) - { - - } - else if (destinationURL != null) - { - return new RedirectResponse(destinationURL); - } - - /* - $executesMethod = $oms->getRelatedInstance($usesBRMB, KnownRelationshipGuids::Method_Binding__executes__Method); - if ($executesMethod === null) - { - trigger_error("task_step: 1; uses BRMB " . $usesBRMB . "; executes method is null"); - } - $usesElement = $oms->getRelatedInstance($executesMethod, KnownRelationshipGuids::Build_UI_Response_Method__uses__Executable_returning_Element); - - $this->updateWorkDataWithElementContents($parentElementContents, $element); - - $usesElementContents = $oms->getRelatedInstances($usesElement, KnownRelationshipGuids::Element__has__Element_Content); - if (count($usesElementContents) > 0) - { - $ecInst0 = $oms->getRelatedInstance($usesElementContents[0], KnownRelationshipGuids::Element_Content__has__Instance); - $this->TargetInstance = $this->Context->getWorkData($ecInst0); - - $this->renderTaskStep2($parentElementContents, $usesElement); - } - exit(); - */ - return FailureResponse.NotImplemented; - } - return FailureResponse.UnexpectedFailure; - } - - private Response? ProcessElementContent(Core.Oms oms, OmsContext context, InstanceHandle elementContent, ReadOnlyDictionary form, string fqecidPrefix) - { - InstanceHandle elementContentInstance = oms.GetRelatedInstance(elementContent, oms.GetInstance(KnownRelationshipGuids.Element_Content__has__Instance)); - if (oms.IsInstanceOf(elementContentInstance, oms.GetInstance(KnownInstanceGuids.Classes.Element))) - { - return ProcessElement(oms, context, elementContentInstance, elementContent, form, fqecidPrefix + oms.GetInstanceKey(elementContentInstance).ToString() + ":"); - } - else if (oms.IsInstanceOf(elementContentInstance, oms.GetInstance(KnownInstanceGuids.Classes.TextAttribute))) - { - string key = fqecidPrefix + oms.GetInstanceKey(elementContent); - string text = oms.GetInstanceText(elementContentInstance); - if (form.ContainsKey(key)) - { - string value = form[key]; - } - } - return null; - } } \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Core.UI.Server/Commands/InstanceCommand.cs b/mocha-dotnet/src/lib/Mocha.Core.UI.Server/Commands/InstanceCommand.cs index 16a60fa..4e865e8 100644 --- a/mocha-dotnet/src/lib/Mocha.Core.UI.Server/Commands/InstanceCommand.cs +++ b/mocha-dotnet/src/lib/Mocha.Core.UI.Server/Commands/InstanceCommand.cs @@ -61,7 +61,7 @@ public abstract class InstanceCommand : TenantedCommand if (context.Session.ContainsKey("OmsContext")) { OmsContext ctx = (OmsContext)context.Session["OmsContext"]; - object? loginToken = ctx.GetWorkData(oms.GetInstance(KnownAttributeGuids.Text.Token)); + string? loginToken = ctx.GetGlobal(oms.GetInstance(KnownAttributeGuids.Text.Token)); if (loginToken != null) { obj.Add("sessionSecureToken", loginToken.ToString()); diff --git a/mocha-dotnet/src/lib/Mocha.Core.UI.Server/OmsServer.cs b/mocha-dotnet/src/lib/Mocha.Core.UI.Server/OmsServer.cs index a968dce..4b64beb 100644 --- a/mocha-dotnet/src/lib/Mocha.Core.UI.Server/OmsServer.cs +++ b/mocha-dotnet/src/lib/Mocha.Core.UI.Server/OmsServer.cs @@ -218,6 +218,7 @@ public class OmsServer // obj.Add("message", String.Format("unknown cmd '{0}'", command)); RespondWithJson(oms, sw, e.Context, 404, "Not Found", obj); } + e.Handled = true; } public void RespondWithJson(Oms oms, StreamWriter sw, WebContext context, int responseCode, string responseText, JsonObject obj) { @@ -228,7 +229,7 @@ public class OmsServer if (context.Session.ContainsKey("OmsContext")) { OmsContext ctx = (OmsContext)context.Session["OmsContext"]; - object? loginToken = ctx.GetWorkData(oms.GetInstance(KnownAttributeGuids.Text.Token)); + string? loginToken = ctx.GetGlobal(oms.GetInstance(KnownAttributeGuids.Text.Token)); if (loginToken != null) { obj.Add("sessionSecureToken", loginToken.ToString()); diff --git a/mocha-dotnet/src/lib/Mocha.Core/KnownInstanceGuids.cs b/mocha-dotnet/src/lib/Mocha.Core/KnownInstanceGuids.cs index 33db4a3..07c17ab 100755 --- a/mocha-dotnet/src/lib/Mocha.Core/KnownInstanceGuids.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/KnownInstanceGuids.cs @@ -481,5 +481,12 @@ namespace Mocha.Core public static Guid Far { get; } = new Guid("{f19d16c7-99ff-48a3-b86a-7db8f400d869}"); public static Guid Center { get; } = new Guid("{63179b92-9a6a-495b-a823-f45e353be9d8}"); } + + public static class Modules + { + public static Guid MochaBaseSystem { get; } = new Guid("{3ffd3a31-208c-49c9-905d-2a69362902ca}"); + public static Guid OOP { get; } = new Guid("{818dfe8d-96ea-4339-8d18-a0e9a5f50908}"); + public static Guid OOPMethodExamples { get; } = new Guid("{5017c102-c154-4ef0-b117-e42bd1c756c1}"); + } } } diff --git a/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/ConditionalSelectAttributeMethodImplementation.cs b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/ConditionalSelectAttributeMethodImplementation.cs index 08b6d5d..b579260 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/ConditionalSelectAttributeMethodImplementation.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/ConditionalSelectAttributeMethodImplementation.cs @@ -34,32 +34,8 @@ public class ConditionalSelectAttributeMethodImplementation : MethodImplementati IEnumerable trueConditions = oms.GetRelatedInstances(cas, oms.GetInstance(KnownRelationshipGuids.Condition_Group__has_true_condition__Executable_returning_Work_Data)); IEnumerable falseConditions = oms.GetRelatedInstances(cas, oms.GetInstance(KnownRelationshipGuids.Condition_Group__has_false_condition__Executable_returning_Work_Data)); bool useAnyCondition = oms.GetAttributeValue(cas, oms.GetInstance(KnownAttributeGuids.Boolean.UseAnyCondition)); - if (trueConditions != null) - { - foreach (InstanceHandle trueCondition in trueConditions) - { - InstanceHandle ret = oms.Execute(context, trueCondition); - object? retval = context.GetWorkData(ret); - if (retval is bool && ((bool)retval)) - { - value = true; - break; - } - } - } - if (falseConditions != null) - { - foreach (InstanceHandle falseCondition in falseConditions) - { - InstanceHandle ret = oms.Execute(context, falseCondition); - object? retval = context.GetWorkData(ret); - if (retval is bool && (!(bool)retval)) - { - value = true; - break; - } - } - } + + value = oms.EvaluateConditions(context, trueConditions, falseConditions, useAnyCondition); if (value) { diff --git a/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/EvaluateBooleanExpressionMethodImplementation.cs b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/EvaluateBooleanExpressionMethodImplementation.cs index 35fc59f..949da2d 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/EvaluateBooleanExpressionMethodImplementation.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/EvaluateBooleanExpressionMethodImplementation.cs @@ -45,80 +45,120 @@ public class EvaluateBooleanExpressionMethodImplementation : MethodImplementatio InstanceHandle source = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Evaluate_Boolean_Expression_Method__has_source__Executable_returning_Work_Data)); InstanceHandle comparison = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Evaluate_Boolean_Expression_Method__uses__Boolean_Operator)); - InstanceHandle target = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Evaluate_Boolean_Expression_Method__has_target__Executable_returning_Work_Data)); - - InstanceHandle[] rtarget_value = new InstanceHandle[0]; + Console.Error.WriteLine("EBE - source {0}", oms.GetGlobalIdentifier(source)); + InstanceHandle rsource = oms.Execute(context, source); object? rsource_valueraw = context.GetWorkData(rsource); - InstanceHandle[] rsource_value = new InstanceHandle[0]; - if (rsource_valueraw is InstanceHandle[]) - { - rsource_value = (InstanceHandle[])rsource_valueraw; - } - else if (rsource_valueraw is InstanceHandle) - { - rsource_value = new InstanceHandle[] { (InstanceHandle)rsource_valueraw }; - } - - if (oms.IsInstanceOf(target, oms.GetInstance(KnownInstanceGuids.Classes.Attribute))) - { - rtarget_value = new InstanceHandle[] { target }; - } - else if (oms.IsInstanceOf(target, oms.GetInstance(KnownInstanceGuids.Classes.Executable))) - { - InstanceHandle rtarget = oms.Execute(context, target); - object? rtarget_valueraw = context.GetWorkData(rtarget); - } - else - { - rtarget_value = new InstanceHandle[] { target }; - } - bool value = false; - - if (comparison == oms.GetInstance(KnownInstanceGuids.RelationalOperators.InSelectionList)) + if (comparison == oms.GetInstance(KnownInstanceGuids.RelationalOperators.IsNotEmpty)) { - if (rtarget_value.ContainsAny(rsource_value)) + if (rsource_valueraw is InstanceHandle) { - value = true; + Console.Error.WriteLine("EBE - is not empty - {0} ?", oms.GetGlobalIdentifier((InstanceHandle)rsource_valueraw)); + + value = ((InstanceHandle)rsource_valueraw) != InstanceHandle.Empty; } - } - else if (comparison == oms.GetInstance(KnownInstanceGuids.RelationalOperators.ExactMatchWithSelectionList)) - { - if (rtarget_value.Length == rsource_value.Length) + else if (rsource_valueraw is IEnumerable) { - List l1 = new List(rsource_value); - List l2 = new List(rtarget_value); - l1.Sort(); - l2.Sort(); - - value = true; - for (int i = 0; i < l1.Count; i++) - { - if (!l1[i].Equals(l2[i])) - { - value = false; - break; - } - } + Console.Error.WriteLine("EBE - is not empty - count = {0} ?", ((IEnumerable)rsource_valueraw).Count()); + + value = ((IEnumerable)rsource_valueraw).Any(); } else { - value = false; + Console.Error.WriteLine("EBE - is not empty - {0} ?", rsource_valueraw); + + value = rsource_valueraw != null; } } - else if (comparison == oms.GetInstance(KnownInstanceGuids.LogicalOperators.EqualTo)) + else if (comparison == oms.GetInstance(KnownInstanceGuids.RelationalOperators.IsEmpty)) { - // ! FIXME ! Implement This ! - value = false; + if (rsource_valueraw is InstanceHandle) + { + value = ((InstanceHandle)rsource_valueraw) == InstanceHandle.Empty; + } + else if (rsource_valueraw is IEnumerable) + { + value = !((IEnumerable)rsource_valueraw).Any(); + } + else + { + value = rsource_valueraw == null; + } } else { - throw new NotImplementedException(String.Format("relational operator '{0}' not implemented @@ {1}, {2}", comparison, oms.GetGlobalIdentifier(method).ToString("B"), context.StackTrace.ToString())); + InstanceHandle target = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Evaluate_Boolean_Expression_Method__has_target__Executable_returning_Work_Data)); + InstanceHandle[] rtarget_value = new InstanceHandle[0]; + + InstanceHandle[] rsource_value = new InstanceHandle[0]; + if (rsource_valueraw is InstanceHandle[]) + { + rsource_value = (InstanceHandle[])rsource_valueraw; + } + else if (rsource_valueraw is InstanceHandle) + { + rsource_value = new InstanceHandle[] { (InstanceHandle)rsource_valueraw }; + } + + if (oms.IsInstanceOf(target, oms.GetInstance(KnownInstanceGuids.Classes.Attribute))) + { + rtarget_value = new InstanceHandle[] { target }; + } + else if (oms.IsInstanceOf(target, oms.GetInstance(KnownInstanceGuids.Classes.Executable))) + { + InstanceHandle rtarget = oms.Execute(context, target); + object? rtarget_valueraw = context.GetWorkData(rtarget); + } + else + { + rtarget_value = new InstanceHandle[] { target }; + } + + if (comparison == oms.GetInstance(KnownInstanceGuids.RelationalOperators.InSelectionList)) + { + if (rtarget_value.ContainsAny(rsource_value)) + { + value = true; + } + } + else if (comparison == oms.GetInstance(KnownInstanceGuids.RelationalOperators.ExactMatchWithSelectionList)) + { + if (rtarget_value.Length == rsource_value.Length) + { + List l1 = new List(rsource_value); + List l2 = new List(rtarget_value); + l1.Sort(); + l2.Sort(); + + value = true; + for (int i = 0; i < l1.Count; i++) + { + if (!l1[i].Equals(l2[i])) + { + value = false; + break; + } + } + } + else + { + value = false; + } + } + else if (comparison == oms.GetInstance(KnownInstanceGuids.LogicalOperators.EqualTo)) + { + // ! FIXME ! Implement This ! + value = false; + } + else + { + throw new NotImplementedException(String.Format("relational operator '{0}' not implemented @@ {1}, {2}", comparison, oms.GetGlobalIdentifier(method).ToString("B"), context.StackTrace.ToString())); + } } - + context.SetWorkData(returnsAttribute, value); return returnsAttribute; } diff --git a/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/GetAttributeMethodImplementation.cs b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/GetAttributeMethodImplementation.cs index db8bfcc..7560eab 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/GetAttributeMethodImplementation.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/GetAttributeMethodImplementation.cs @@ -40,9 +40,16 @@ public class GetAttributeMethodImplementation : MethodImplementation { forInstance = (InstanceHandle?) context.GetWorkData(forInstance.Value); } - - object? value = oms.UnsafeGetAttributeValue((InstanceHandle) forInstance, returnsAttribute); - context.SetWorkData(returnsAttribute, value); + + if (forInstance is InstanceHandle forInstanceHandle) + { + object? value = oms.UnsafeGetAttributeValue((InstanceHandle)forInstanceHandle, returnsAttribute); + context.SetWorkData(returnsAttribute, value); + } + else + { + Console.Error.WriteLine("no for instance IS"); + } return returnsAttribute; } } \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/GetInstanceSetBySystemRoutineMethodImplementation.cs b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/GetInstanceSetBySystemRoutineMethodImplementation.cs new file mode 100644 index 0000000..6a7c466 --- /dev/null +++ b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/GetInstanceSetBySystemRoutineMethodImplementation.cs @@ -0,0 +1,38 @@ +// Copyright (C) 2024 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 . + +namespace Mocha.Core.MethodImplementations; + +public class GetInstanceSetBySystemRoutineMethodImplementation : MethodImplementation +{ + public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.GetInstanceSetBySystemRoutineMethod; + protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) + { + InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class)); + InstanceHandle returnsWorkSet = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Get_Instance_Set_by_System_Routine_Method__returns__Work_Set)); + InstanceHandle usesSystemInstanceSetRoutine = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Get_Instance_Set_by_System_Routine_Method__uses__System_Instance_Set_Routine)); + + if (returnsWorkSet == InstanceHandle.Empty) + { + throw new InvalidOperationException("no return Attribute specified for method"); + } + + object? value = oms.ExecuteSystemRoutine(context, usesSystemInstanceSetRoutine); + context.SetWorkData(returnsWorkSet, value); + return returnsWorkSet; + } +} \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/ProcessRelatedUpdatesMethodImplementation.cs b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/ProcessRelatedUpdatesMethodImplementation.cs index 793e5f4..9f2e506 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/ProcessRelatedUpdatesMethodImplementation.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/ProcessRelatedUpdatesMethodImplementation.cs @@ -25,9 +25,12 @@ public class ProcessRelatedUpdatesMethodImplementation : MethodImplementation InstanceHandle forClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class)); IEnumerable usesExecutableForPUMB = oms.GetRelatedInstances(method, oms.GetInstance(KnownRelationshipGuids.Process_Related_Updates_Method__uses__Executable_for_PUMB)); + Console.Error.WriteLine("---> has {0} PUMBs", usesExecutableForPUMB.Count()); + foreach (InstanceHandle pumb in usesExecutableForPUMB) { - oms.Execute(context, pumb); + Console.Error.WriteLine("---> executing PUMB {0}", pumb.GlobalIdentifier); + oms.Execute(context, pumb) ; } return InstanceHandle.Empty; } diff --git a/mocha-dotnet/src/lib/Mocha.Core/Oms.cs b/mocha-dotnet/src/lib/Mocha.Core/Oms.cs index 6c63e86..19cdcba 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/Oms.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/Oms.cs @@ -21,6 +21,7 @@ using System.Collections.ObjectModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Data.SqlTypes; +using System.Diagnostics; using System.Diagnostics.Contracts; using System.Net; using System.Numerics; @@ -72,6 +73,37 @@ public abstract class Oms UpdateSyntacticSugar(); + RegisterSystemInstanceSetRoutine(KnownInstanceGuids.SystemInstanceSetRoutines.GetCurrentUser, delegate (Oms oms, OmsContext context) + { + Console.Error.WriteLine("oms: executing system instance set routine {0}", KnownInstanceGuids.SystemUpdateRoutines.LoginUser); + + InstanceHandle a_Token = oms.GetInstance(KnownAttributeGuids.Text.Token); + string token = context.GetGlobal(a_Token); + if (token != null) + { + IEnumerable userLogins = oms.GetInstancesOf(oms.GetInstance(KnownInstanceGuids.Classes.UserLogin)); + InstanceHandle r_User_Login__has__User = oms.GetInstance(KnownRelationshipGuids.User_Login__has__User); + + foreach (InstanceHandle userLogin in userLogins) + { + string compareToken = oms.GetAttributeValue(userLogin, a_Token); + Console.Error.WriteLine("oms: token {0} == {1} ???", token, compareToken); + + if (compareToken.Equals(token)) + { + InstanceHandle user = oms.GetRelatedInstance(userLogin, r_User_Login__has__User); + Console.Error.WriteLine("yes, returning {0}", user.GlobalIdentifier); + + return new InstanceHandle[] { user }; + } + } + } + else + { + Console.Error.WriteLine("oms: error: login token not set"); + } + return new InstanceHandle[0]; + }); RegisterSystemAttributeRoutine(KnownInstanceGuids.SystemAttributeRoutines.GetInstanceText, delegate (Oms oms, OmsContext context) { object? val = context.GetWorkData(oms.GetInstance(KnownInstanceGuids.Classes.Instance)); @@ -103,6 +135,8 @@ public abstract class Oms }); RegisterSystemUpdateRoutine(KnownInstanceGuids.SystemUpdateRoutines.LoginUser, delegate (Oms oms, OmsContext context) { + Console.Error.WriteLine("oms: executing system update routine {0}", KnownInstanceGuids.SystemUpdateRoutines.LoginUser); + // FIXME: these are ECs for now, they should probably be Text Attributes (or parms?) passed into the US method Guid userNameGuid = new Guid("{c67f305e-bd4d-4628-816b-55fb85ea1b67}"); Guid passwordGuid = new Guid("{51b51be3-44fd-48f1-971f-682aee0a6132}"); @@ -120,10 +154,14 @@ public abstract class Oms foreach (InstanceHandle user in users) { + Console.Error.WriteLine("looking at user {0}", user.GlobalIdentifier); + string expectedUserName = oms.GetAttributeValue(user, oms.GetInstance(KnownAttributeGuids.Text.UserName)); if (expectedUserName == null) continue; + Console.Error.WriteLine("... expected user name '{0}', actual user name '{1}'", expectedUserName, userName); + if (expectedUserName != userName) continue; @@ -137,6 +175,8 @@ public abstract class Oms byte[] hash = hashAlgorithm.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password + passwordSalt)); string actualPasswordHash = Convert.ToHexString(hash).ToLowerInvariant(); + Console.Error.WriteLine("... expected password hash '{0}'\n... actual password hash '{1}'", expectedPasswordHash, actualPasswordHash); + if (actualPasswordHash.Equals(expectedPasswordHash)) { actualSystemUser = user; @@ -147,8 +187,12 @@ public abstract class Oms if (sessionSecureToken != null) { + Console.Error.WriteLine("!! success !! set secure token {0}", sessionSecureToken); + Console.Error.WriteLine("!! success !! current system user is {0}", actualSystemUser.GlobalIdentifier); + context.SetWorkData(oms.GetInstance(KnownInstanceGuids.Classes.User), actualSystemUser); context.SetWorkData(oms.GetInstance(KnownAttributeGuids.Text.Token), sessionSecureToken); + context.SetGlobal(oms.GetInstance(KnownAttributeGuids.Text.Token), sessionSecureToken); // FIXME: this should be processed in the PRU InstanceHandle clsSystemAccountSignon = GetInstance(KnownInstanceGuids.Classes.UserLogin); @@ -905,7 +949,8 @@ public abstract class Oms InstanceHandle parentClass = GetParentClass(methodOrMethodBinding); Guid parentClassId = GetGlobalIdentifier(parentClass); - context.StackTrace.Push(methodOrMethodBinding); + context.Push(methodOrMethodBinding); + // context.StackTrace.Push(methodOrMethodBinding); InstanceHandle? retval = null; @@ -949,7 +994,14 @@ public abstract class Oms } else { - context.StackTrace.Pop(); + // context.StackTrace.Pop(); + IDictionary dict = context.GetAllWorkData(); + context.Pop(); + + if (dict.ContainsKey(retval.Value)) + { + context.SetWorkData(retval.Value, dict[retval.Value]); + } return retval.Value; } } @@ -965,7 +1017,7 @@ public abstract class Oms return new OmsContext(this); } - public IReadOnlyCollection ExecuteStaticMethodReturningInstanceSet(OmsContext context, ReturnInstanceSetMethodBinding methodBinding) + public IEnumerable ExecuteStaticMethodReturningInstanceSet(OmsContext context, ReturnInstanceSetMethodBinding methodBinding) { InstanceHandle method = GetRelatedInstance(methodBinding.Handle, GetInstance(KnownRelationshipGuids.Method_Binding__executes__Method)); if (TryGetAttributeValue(method, GetInstance(KnownAttributeGuids.Boolean.Static), out bool is_static)) @@ -975,10 +1027,14 @@ public abstract class Oms InstanceHandle result = Execute(context, methodBinding); object? value = context.GetWorkData(result); - if (value is IReadOnlyCollection res) + if (value is IEnumerable res) { return res; } + else if (value is InstanceHandle res_singular) + { + return new InstanceHandle[] { res_singular }; + } } } throw new InvalidOperationException("cannot call a non-static Method in a static context"); @@ -1607,7 +1663,7 @@ public abstract class Oms return false; } - public void UpdateElementContents(OmsContext context, InstanceHandle element, ReadOnlyDictionary values) + private void UpdateElementContents(OmsContext context, InstanceHandle element, IDictionary values) { IEnumerable elementContents = GetRelatedInstances(element, GetInstance(KnownRelationshipGuids.Element__has__Element_Content)); foreach (InstanceHandle elementContent in elementContents) @@ -1664,24 +1720,139 @@ public abstract class Oms } } - public Response ProcessElement(OmsContext context, InstanceHandle initiatingElement, InstanceHandle parmInstance) + public string GetLabelForUIElement(InstanceHandle parentElementContent) { - if (parmInstance != InstanceHandle.Empty) + InstanceHandle parentInstance = GetRelatedInstance(parentElementContent, GetInstance(KnownRelationshipGuids.Element_Content__has__Instance)); + string label = GetAttributeValue(parentElementContent, GetInstance(KnownAttributeGuids.Text.LabelOverride)); + if (label == null) { - InstanceHandle processedByCt = GetRelatedInstance(initiatingElement, GetInstance(KnownRelationshipGuids.Element__processed_by__Control_Transaction_Method)); - InstanceHandle forClassId = GetRelatedInstance(processedByCt, GetInstance(KnownRelationshipGuids.Method__for__Class)); + label = GetAttributeValue(parentElementContent, GetInstance(KnownAttributeGuids.Text.Label)); + if (label == null) + { + label = GetInstanceText(parentInstance); + } + } + return label; + } - InstanceHandle buildsResponseWithMB = GetRelatedInstance(processedByCt, GetInstance(KnownRelationshipGuids.Control_Transaction_Method__uses__Build_Response_Method_Binding)); + + + public Response ProcessElement(OmsContext ctx, InstanceHandle element, IDictionary? form = null, string fqecidPrefix = "") + { + if (form != null) + { + /* + InstanceHandle processedByCt2 = GetRelatedInstance(element, GetInstance(KnownRelationshipGuids.Element__processed_by__Control_Transaction_Method)); + InstanceHandle forClassId = GetRelatedInstance(processedByCt2, GetInstance(KnownRelationshipGuids.Method__for__Class)); + + InstanceHandle buildsResponseWithMB = GetRelatedInstance(processedByCt2, GetInstance(KnownRelationshipGuids.Control_Transaction_Method__uses__Build_Response_Method_Binding)); InstanceHandle executesMethod = GetRelatedInstance(buildsResponseWithMB, GetInstance(KnownRelationshipGuids.Method_Binding__executes__Method)); InstanceHandle usesExecutableReturningElement = GetRelatedInstance(executesMethod, GetInstance(KnownRelationshipGuids.Build_UI_Response_Method__uses__Executable_returning_Element)); - context.SetWorkData(forClassId, parmInstance); - return ProcessElement(context, usesExecutableReturningElement, InstanceHandle.Empty); + ctx.SetWorkData(forClassId, processingInstance); + return ProcessElement(ctx, usesExecutableReturningElement, InstanceHandle.Empty, form); + */ + + // first we process the related updates + InstanceHandle processedByPru = GetRelatedInstance(element, GetInstance(KnownRelationshipGuids.Element__processed_by__Process_Related_Updates_Method)); + if (processedByPru != InstanceHandle.Empty) + { + // this works... so far + Console.Error.WriteLine("oms: processing element with PRU {0}", processedByPru.GlobalIdentifier); + // hack + UpdateElementContents(ctx, element, form); + Execute(ctx, processedByPru); + /* + $executesMethod = $oms->getRelatedInstance($usesBRMB, KnownRelationshipGuids::Method_Binding__executes__Method); + if ($executesMethod === null) + { + trigger_error("task_step: 1; uses BRMB " . $usesBRMB . "; executes method is null"); + } + $usesElement = $oms->getRelatedInstance($executesMethod, KnownRelationshipGuids::Build_UI_Response_Method__uses__Executable_returning_Element); + + $this->updateWorkDataWithElementContents($parentElementContents, $element); + + $usesElementContents = $oms->getRelatedInstances($usesElement, KnownRelationshipGuids::Element__has__Element_Content); + if (count($usesElementContents) > 0) + { + $ecInst0 = $oms->getRelatedInstance($usesElementContents[0], KnownRelationshipGuids::Element_Content__has__Instance); + $this->TargetInstance = $this->Context->getWorkData($ecInst0); + + $this->renderTaskStep2($parentElementContents, $usesElement); + } + exit(); + */ + } + + // ... then we process the element contents... + IEnumerable elementContents = GetRelatedInstances(element, GetInstance(KnownRelationshipGuids.Element__has__Element_Content)); + foreach (InstanceHandle elementContent2 in elementContents) + { + Response? resp = ProcessElementContent(ctx, elementContent2, form, fqecidPrefix); + if (resp != null) + { + return resp; + } + } + + // ... finally we run the CT - Control Transaction Method to return the response + InstanceHandle processedByCt = GetRelatedInstance(element, GetInstance(KnownRelationshipGuids.Element__processed_by__Control_Transaction_Method)); + if (processedByCt != InstanceHandle.Empty) + { + Console.Error.WriteLine("oms: processing element with CT {0}", processedByCt.GlobalIdentifier); + // hack + IEnumerable usesBuildResponseMethodBindings = GetRelatedInstances(processedByCt, GetInstance(KnownRelationshipGuids.Control_Transaction_Method__uses__Build_Response_Method_Binding)); + Console.Error.WriteLine("---> has {0} BRMBs", usesBuildResponseMethodBindings.Count()); + + foreach (InstanceHandle usesBuildResponseMethodBinding in usesBuildResponseMethodBindings) + { + Console.Error.WriteLine("oms: evaluating BRMB {0}", usesBuildResponseMethodBinding.GlobalIdentifier); + + IEnumerable trueConditions = GetRelatedInstances(usesBuildResponseMethodBinding, GetInstance(KnownRelationshipGuids.Condition_Group__has_true_condition__Executable_returning_Work_Data)); + IEnumerable falseConditions = GetRelatedInstances(usesBuildResponseMethodBinding, GetInstance(KnownRelationshipGuids.Condition_Group__has_false_condition__Executable_returning_Work_Data)); + bool useAnyCondition = GetAttributeValue(usesBuildResponseMethodBinding, GetInstance(KnownAttributeGuids.Boolean.UseAnyCondition)); + + if (EvaluateConditions(ctx, trueConditions, falseConditions, useAnyCondition)) + { + InstanceHandle executesMethod = GetRelatedInstance(usesBuildResponseMethodBinding, GetInstance(KnownRelationshipGuids.Method_Binding__executes__Method)); + Console.Error.WriteLine("----> ok, executing method {0}", executesMethod.GlobalIdentifier); + + // execute BRMB + string targetURL = GetAttributeValue(executesMethod, GetInstance(KnownAttributeGuids.Text.TargetURL)); + if (targetURL != null) + { + return new RedirectResponse(targetURL); + } + } + } + + /* + $executesMethod = $oms->getRelatedInstance($usesBRMB, KnownRelationshipGuids::Method_Binding__executes__Method); + if ($executesMethod === null) + { + trigger_error("task_step: 1; uses BRMB " . $usesBRMB . "; executes method is null"); + } + $usesElement = $oms->getRelatedInstance($executesMethod, KnownRelationshipGuids::Build_UI_Response_Method__uses__Executable_returning_Element); + + $this->updateWorkDataWithElementContents($parentElementContents, $element); + + $usesElementContents = $oms->getRelatedInstances($usesElement, KnownRelationshipGuids::Element__has__Element_Content); + if (count($usesElementContents) > 0) + { + $ecInst0 = $oms->getRelatedInstance($usesElementContents[0], KnownRelationshipGuids::Element_Content__has__Instance); + $this->TargetInstance = $this->Context->getWorkData($ecInst0); + + $this->renderTaskStep2($parentElementContents, $usesElement); + } + exit(); + */ + return FailureResponse.NotImplemented; + } } else { Renderer renderer = new Renderer(this); - Widget widget = renderer.Parse(context, initiatingElement, InstanceHandle.Empty, InstanceHandle.Empty); + Widget widget = renderer.Parse(ctx, element, InstanceHandle.Empty, InstanceHandle.Empty); if (widget == null) { return FailureResponse.UnexpectedFailure; @@ -1704,18 +1875,74 @@ public abstract class Oms return FailureResponse.UnexpectedFailure; } - public string GetLabelForUIElement(InstanceHandle parentElementContent) - { - InstanceHandle parentInstance = GetRelatedInstance(parentElementContent, GetInstance(KnownRelationshipGuids.Element_Content__has__Instance)); - string label = GetAttributeValue(parentElementContent, GetInstance(KnownAttributeGuids.Text.LabelOverride)); - if (label == null) + private Response? ProcessElementContent(OmsContext context, InstanceHandle elementContent, IDictionary form, string fqecidPrefix) + { + InstanceHandle elementContentInstance = GetRelatedInstance(elementContent, GetInstance(KnownRelationshipGuids.Element_Content__has__Instance)); + if (IsInstanceOf(elementContentInstance, GetInstance(KnownInstanceGuids.Classes.Element))) { - label = GetAttributeValue(parentElementContent, GetInstance(KnownAttributeGuids.Text.Label)); - if (label == null) + return ProcessElement(context, elementContentInstance, form, fqecidPrefix + GetInstanceKey(elementContentInstance).ToString() + ":"); + } + else if (IsInstanceOf(elementContentInstance, GetInstance(KnownInstanceGuids.Classes.TextAttribute))) + { + string key = fqecidPrefix + GetInstanceKey(elementContent); + string text = GetInstanceText(elementContentInstance); + if (form.ContainsKey(key)) { - label = GetInstanceText(parentInstance); + string value = form[key]; } } - return label; - } + return null; + } + + private HashAlgorithm hashAlgorithm = System.Security.Cryptography.SHA512.Create(); + + public InstanceHandle CreateUser(string username, string password) + { + InstanceHandle c_User = GetInstance(KnownInstanceGuids.Classes.User); + InstanceHandle a_UserName = GetInstance(KnownAttributeGuids.Text.UserName); + InstanceHandle a_PasswordSalt = GetInstance(KnownAttributeGuids.Text.PasswordSalt); + InstanceHandle a_PasswordHash = GetInstance(KnownAttributeGuids.Text.PasswordHash); + + string salt = Guid.NewGuid().ToString("N").ToLowerInvariant(); + string hash = Convert.ToHexString(hashAlgorithm.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password + salt))).ToLowerInvariant(); + + InstanceHandle i_User = CreateInstanceOf(c_User); + SetAttributeValue(i_User, a_UserName, username); + SetAttributeValue(i_User, a_PasswordSalt, salt); + SetAttributeValue(i_User, a_PasswordHash, hash); + + return i_User; + } + + public bool EvaluateConditions(OmsContext context, IEnumerable trueConditions, IEnumerable falseConditions, bool useAnyCondition) + { + bool value = false; + if (trueConditions != null) + { + foreach (InstanceHandle trueCondition in trueConditions) + { + InstanceHandle ret = Execute(context, trueCondition); + object? retval = context.GetWorkData(ret); + if (retval is bool && ((bool)retval)) + { + value = true; + break; + } + } + } + if (falseConditions != null) + { + foreach (InstanceHandle falseCondition in falseConditions) + { + InstanceHandle ret = Execute(context, falseCondition); + object? retval = context.GetWorkData(ret); + if (retval is bool && (!(bool)retval)) + { + value = true; + break; + } + } + } + return value; + } } diff --git a/mocha-dotnet/src/lib/Mocha.Core/OmsContext.cs b/mocha-dotnet/src/lib/Mocha.Core/OmsContext.cs index c977b23..1749816 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/OmsContext.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/OmsContext.cs @@ -25,6 +25,7 @@ public class OmsContext { public Oms Oms { get; } public OmsStackTrace StackTrace { get; } + private Stack> WorkDataSets = new Stack>(); internal OmsContext(Oms oms) { @@ -33,6 +34,7 @@ public class OmsContext } private Dictionary _WorkData = new Dictionary(); + private Dictionary _GlobalData = new Dictionary(); public object? GetWorkData(WorkSet parm) { return GetWorkData(parm.Handle); @@ -42,6 +44,12 @@ public class OmsContext if (_WorkData.ContainsKey(parm)) return _WorkData[parm]; + foreach (Dictionary set in WorkDataSets) + { + if (set.ContainsKey(parm)) + return set[parm]; + } + // Console.Error.WriteLine("work data not found for parm {0}", Oms.GetGlobalIdentifier(parm)); return null; } @@ -108,6 +116,8 @@ public class OmsContext } } } + + value = ((IEnumerable)value).FirstOrDefault(); } else if (value is IEnumerable) { @@ -141,4 +151,39 @@ public class OmsContext } _WorkData[parm] = value; } + + public void Push(InstanceHandle methodOrMethodBinding) + { + StackTrace.Push(methodOrMethodBinding); + WorkDataSets.Push(_WorkData); + + _WorkData = new Dictionary(); + } + public InstanceHandle Pop() + { + InstanceHandle methodOrMethodBinding = StackTrace.Pop(); + _WorkData = WorkDataSets.Pop(); + return methodOrMethodBinding; + } + + public IDictionary GetAllWorkData() + { + return _WorkData; + } + + public T GetGlobal(InstanceHandle parm, T defaultValue = default(T)) + { + if (_GlobalData.ContainsKey(parm)) + { + if (_GlobalData[parm] is T) + { + return (T)(_GlobalData[parm]); + } + } + return defaultValue; + } + public void SetGlobal(InstanceHandle parm, object? value) + { + _GlobalData[parm] = value; + } } \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Core/UI/Widget.cs b/mocha-dotnet/src/lib/Mocha.Core/UI/Widget.cs index 8cfd752..04b1274 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/UI/Widget.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/UI/Widget.cs @@ -74,8 +74,11 @@ public abstract class Widget if (!displayOptions.Contains(OMS.GetInstance(KnownInstanceGuids.ElementContentDisplayOptions.DoNotShowLabel))) { - string label = OMS.GetLabelForUIElement(ParentElementContent); - obj.Add("label", label); + if (!OMS.IsInstanceOf(ParentInstance, OMS.GetInstance(KnownInstanceGuids.Classes.Element))) + { + string label = OMS.GetLabelForUIElement(ParentElementContent); + obj.Add("label", label); + } } if (!ShouldBeEnabled()) { 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 fb0c3bc..687e469 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/Element.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/Element.cs @@ -59,7 +59,7 @@ public class Element : Widget // otherwise, we are a hbox // return "hbox"; - return "vbox"; + return "fieldSet"; } } diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/CommonTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/CommonTests.cs index 406b029..7ba0621 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/CommonTests.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/CommonTests.cs @@ -41,7 +41,7 @@ public class CommonTests : MethodTestsBase Assert.That(delegate () { - IReadOnlyCollection specifiedInstances = Oms.ExecuteStaticMethodReturningInstanceSet(context, dummyMethodRsmb); + IEnumerable specifiedInstances = Oms.ExecuteStaticMethodReturningInstanceSet(context, dummyMethodRsmb); }, Throws.InvalidOperationException); } diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/GetSpecifiedInstancesMethodTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/GetSpecifiedInstancesMethodTests.cs index 71d9bf3..71d4b34 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/GetSpecifiedInstancesMethodTests.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/GetSpecifiedInstancesMethodTests.cs @@ -44,7 +44,7 @@ public class GetSpecifiedInstancesMethodTests : MethodTestsBase nom = Oms.GetInstanceText(gsiMethodRsmb); OmsContext context = Oms.CreateContext(); - IReadOnlyCollection specifiedInstances = Oms.ExecuteStaticMethodReturningInstanceSet(context, gsiMethodRsmb); + IEnumerable specifiedInstances = Oms.ExecuteStaticMethodReturningInstanceSet(context, gsiMethodRsmb); Assert.That(specifiedInstances, Contains.Item(irTestClassInstance)); } diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/ModuleTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/ModuleTests.cs new file mode 100644 index 0000000..9317c35 --- /dev/null +++ b/mocha-dotnet/tests/Mocha.Core.Tests/ModuleTests.cs @@ -0,0 +1,94 @@ +using System; +using Mocha.Core.Oop; + +namespace Mocha.Core.Tests; + +[TestFixture] +public class ModuleTests : OmsTestsBase +{ + [Test] + public void ToplevelModuleInstanceText() + { + InstanceHandle ihMochaBaseSystem = Oms.GetInstance(KnownInstanceGuids.Modules.MochaBaseSystem); + + string text = Oms.GetInstanceText(ihMochaBaseSystem); + Assert.That(text, Is.EqualTo("Mocha Base System")); + } + [Test] + public void SublevelModuleInstanceText() + { + InstanceHandle ihOOPMethodExamples = Oms.GetInstance(KnownInstanceGuids.Modules.OOPMethodExamples); + string text = Oms.GetInstanceText(ihOOPMethodExamples); + Assert.That(text, Is.EqualTo("Mocha Base System:OOP:OOP Method Examples")); + } + + [Test] + public void TopLevelModuleName() + { + InstanceHandle ihMochaBaseSystem = Oms.GetInstance(KnownInstanceGuids.Modules.MochaBaseSystem); + + InstanceHandle c_Module = Oms.GetInstance(KnownInstanceGuids.Classes.Module); + Method Module__get__Name = Oms.GetMethod(c_Module, "get", "Name"); + Assert.That(Module__get__Name, Is.Not.Null); + // + OmsContext context = Oms.CreateContext(); + InstanceHandle ret = Oms.Execute(context, Module__get__Name, ihMochaBaseSystem); + object? val = context.GetWorkData(ret); + Assert.That(val, Is.TypeOf().And.EqualTo("Mocha Base System")); + } + + [Test] + public void OOPMethodExamples_ParentModuleIs_OOP() + { + InstanceHandle ihOOPMethodExamples = Oms.GetInstance(KnownInstanceGuids.Modules.OOPMethodExamples); + InstanceHandle ihOOP = Oms.GetInstance(KnownInstanceGuids.Modules.OOP); + + InstanceHandle c_Module = Oms.GetInstance(KnownInstanceGuids.Classes.Module); + Method Module__get__Parent_Module = Oms.GetMethod(c_Module, "get", "Parent Module"); + Assert.That(Module__get__Parent_Module, Is.Not.Null); + + OmsContext context = Oms.CreateContext(); + InstanceHandle ret = Oms.Execute(context, Module__get__Parent_Module, ihOOPMethodExamples); + object? val = context.GetWorkData(ret); + + Assert.That(val, Is.TypeOf().And.EqualTo(ihOOP)); + } + + [Test] + public void MochaBaseSystem_ParentModuleIs_Empty() + { + InstanceHandle ihMochaBaseSystem = Oms.GetInstance(KnownInstanceGuids.Modules.MochaBaseSystem); + + InstanceHandle c_Module = Oms.GetInstance(KnownInstanceGuids.Classes.Module); + Method Module__get__Parent_Module = Oms.GetMethod(c_Module, "get", "Parent Module"); + Assert.That(Module__get__Parent_Module, Is.Not.Null); + + OmsContext context = Oms.CreateContext(); + InstanceHandle ret = Oms.Execute(context, Module__get__Parent_Module, ihMochaBaseSystem); + object? val = context.GetWorkData(ret); + + Assert.That(val, Is.Null.Or.EqualTo(InstanceHandle.Empty)); + } + + [Test] + public void Module__get__Fully_Qualified_Name__method_components() + { + InstanceHandle ihMochaBaseSystem = Oms.GetInstance(KnownInstanceGuids.Modules.MochaBaseSystem); + + InstanceHandle c_Module = Oms.GetInstance(KnownInstanceGuids.Classes.Module); + InstanceHandle method = Oms.GetInstance(new Guid("{0ab85e0b-5577-475a-b914-4578ffb928d7}")); + + IEnumerable ms = Oms.GetRelatedInstances(method, Oms.GetInstance(KnownRelationshipGuids.Build_Attribute_Method__builds_with__Build_Attribute_Method_Component)); + + InstanceHandle m2 = Oms.GetInstance(new Guid("{27b070c9-7130-414b-960d-511f2836ef06}")); + + IEnumerable ms2 = Oms.GetRelatedInstances(method, Oms.GetInstance(KnownRelationshipGuids.Build_Attribute_Method__builds_with__Build_Attribute_Method_Component)); + + OmsContext context = Oms.CreateContext(); + InstanceHandle ret = Oms.Execute(context, method, ihMochaBaseSystem); + object? val = context.GetWorkData(ret); + + + } + +} diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/UI/UITests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/UI/UITests.cs new file mode 100644 index 0000000..11fbcaa --- /dev/null +++ b/mocha-dotnet/tests/Mocha.Core.Tests/UI/UITests.cs @@ -0,0 +1,73 @@ +using System; +using System.Text.Json.Nodes; + +namespace Mocha.Core.Tests.UI; + +[TestFixture] +public class UITests : OmsTestsBase +{ + + [Test] + public void LoginPageElement() + { + InstanceHandle loginPage = Oms.GetInstance(KnownInstanceGuids.Pages.LoginPage); + + OmsContext context = Oms.CreateContext(); + Response pageOutput = Oms.ProcessElement(context, loginPage); + + JsonObject json = pageOutput.GetResponse(Oms, context); + + Assert.That(json["result"].GetValue(), Is.EqualTo("success")); + Assert.That(json["value"]["body"]["widget"].GetValue(), Is.EqualTo("fieldSet")); + } + + [Test] + public void LoginPageElementSubmit() + { + Oms.CreateUser("testing", "testing"); + + InstanceHandle loginPage = Oms.GetInstance(KnownInstanceGuids.Pages.LoginPage); + + InstanceHandle loginPageSubedit = Oms.GetInstance(new Guid("{2b7d4481-b7c2-4e26-a917-e3ff7c367a8a}")); + OmsContext context = Oms.CreateContext(); + + Dictionary dict = new Dictionary(); + dict["{c67f305e-bd4d-4628-816b-55fb85ea1b67}"] = "testing"; + dict["{51b51be3-44fd-48f1-971f-682aee0a6132}"] = "testing"; + + Response pageOutput = Oms.ProcessElement(context, loginPageSubedit, dict); + JsonObject json = pageOutput.GetResponse(Oms, context); + + string s_Token = context.GetGlobal(Oms.GetInstance(KnownAttributeGuids.Text.Token)); + Assert.That(s_Token, Is.Not.Empty); + + Assert.That(json["result"].GetValue(), Is.EqualTo("success")); + Assert.That(json["type"].GetValue(), Is.EqualTo("redirect")); + Assert.That(json["destinationUrl"].GetValue(), Is.EqualTo("~/d/home.htmld")); + } + + [Test] + public void LoginPageElementSubmitBadPassword() + { + InstanceHandle loginPage = Oms.GetInstance(KnownInstanceGuids.Pages.LoginPage); + + InstanceHandle loginPageSubedit = Oms.GetInstance(new Guid("{2b7d4481-b7c2-4e26-a917-e3ff7c367a8a}")); + OmsContext context = Oms.CreateContext(); + + Dictionary dict = new(); + dict["{c67f305e-bd4d-4628-816b-55fb85ea1b67}"] = "superuser"; + dict["{51b51be3-44fd-48f1-971f-682aee0a6132}"] = "testing"; + + Response pageOutput = Oms.ProcessElement(context, loginPageSubedit, dict); + + object i_User = context.GetWorkData(Oms.GetInstance(KnownInstanceGuids.Classes.User)); + Assert.That(i_User, Is.Null); + + JsonObject json = pageOutput.GetResponse(Oms, context); + + // ??? should this return a result=failure? + Assert.That(json["result"].GetValue(), Is.EqualTo("success")); + Assert.That(json["type"].GetValue(), Is.EqualTo("redirect")); + Assert.That(json["destinationUrl"].GetValue(), Does.StartWith("~/d/logout.htmld")); + } +}