diff --git a/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers.Tests/FormObjectHelpersTests.cs b/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers.Tests/FormObjectHelpersTests.cs index c6f3e51..75513a8 100644 --- a/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers.Tests/FormObjectHelpersTests.cs +++ b/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers.Tests/FormObjectHelpersTests.cs @@ -12,6 +12,8 @@ public class FormObjectHelpersTests [DataRow("Enabled")] [DataRow("Locked")] [DataRow("Unlocked")] + [DataRow("Required")] + [DataRow("Optional")] public void SetField_FormObject_WithNullFieldNumber_ThrowsArgumentNullException(string operation) { // Arrange @@ -25,6 +27,8 @@ public void SetField_FormObject_WithNullFieldNumber_ThrowsArgumentNullException( "Enabled" => () => form.SetEnabledField(null!), "Locked" => () => form.SetLockedField(null!), "Unlocked" => () => form.SetUnlockedField(null!), + "Required" => () => form.SetRequiredField(null!), + "Optional" => () => form.SetOptionalField(null!), _ => throw new ArgumentOutOfRangeException(nameof(operation)) }; @@ -37,6 +41,8 @@ public void SetField_FormObject_WithNullFieldNumber_ThrowsArgumentNullException( [DataRow("Enabled")] [DataRow("Locked")] [DataRow("Unlocked")] + [DataRow("Required")] + [DataRow("Optional")] public void SetField_FormObject_WithEmptyFieldNumber_ThrowsArgumentException(string operation) { // Arrange @@ -50,6 +56,8 @@ public void SetField_FormObject_WithEmptyFieldNumber_ThrowsArgumentException(str "Enabled" => () => form.SetEnabledField(string.Empty), "Locked" => () => form.SetLockedField(string.Empty), "Unlocked" => () => form.SetUnlockedField(string.Empty), + "Required" => () => form.SetRequiredField(string.Empty), + "Optional" => () => form.SetOptionalField(string.Empty), _ => throw new ArgumentOutOfRangeException(nameof(operation)) }; @@ -57,6 +65,172 @@ public void SetField_FormObject_WithEmptyFieldNumber_ThrowsArgumentException(str Assert.ThrowsException(act); } + [DataTestMethod] + [DataRow("Disabled")] + [DataRow("Enabled")] + [DataRow("Locked")] + [DataRow("Unlocked")] + [DataRow("Required")] + [DataRow("Optional")] + public void SetField_FormObject_WithFieldOnlyInOtherRow_OnlyAppliesToMatchingRow(string operation) + { + // Arrange + var form = new FormObject { CurrentRow = new RowObject { RowId = "1", RowAction = string.Empty }, MultipleIteration = true }; + var otherRow = new RowObject { RowId = "2", RowAction = string.Empty }; + + switch (operation) + { + case "Disabled": + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "200", Enabled = "1" }); + otherRow.Fields.Add(new FieldObject { FieldNumber = "100", Enabled = "1" }); + form.OtherRows.Add(otherRow); + + form.SetDisabledField("100"); + + Assert.AreEqual("1", form.CurrentRow.Fields[0].Enabled); + Assert.AreEqual("0", otherRow.Fields[0].Enabled); + break; + case "Enabled": + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "200", Enabled = "0" }); + otherRow.Fields.Add(new FieldObject { FieldNumber = "100", Enabled = "0" }); + form.OtherRows.Add(otherRow); + + form.SetEnabledField("100"); + + Assert.AreEqual("0", form.CurrentRow.Fields[0].Enabled); + Assert.AreEqual("1", otherRow.Fields[0].Enabled); + break; + case "Locked": + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "200", Lock = "0" }); + otherRow.Fields.Add(new FieldObject { FieldNumber = "100", Lock = "0" }); + form.OtherRows.Add(otherRow); + + form.SetLockedField("100"); + + Assert.AreEqual("0", form.CurrentRow.Fields[0].Lock); + Assert.AreEqual("1", otherRow.Fields[0].Lock); + break; + case "Unlocked": + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "200", Lock = "1" }); + otherRow.Fields.Add(new FieldObject { FieldNumber = "100", Lock = "1" }); + form.OtherRows.Add(otherRow); + + form.SetUnlockedField("100"); + + Assert.AreEqual("1", form.CurrentRow.Fields[0].Lock); + Assert.AreEqual("0", otherRow.Fields[0].Lock); + break; + case "Required": + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "200", Required = "0" }); + otherRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "0" }); + form.OtherRows.Add(otherRow); + + form.SetRequiredField("100"); + + Assert.AreEqual("0", form.CurrentRow.Fields[0].Required); + Assert.AreEqual("1", otherRow.Fields[0].Required); + break; + case "Optional": + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "200", Required = "1" }); + otherRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "1" }); + form.OtherRows.Add(otherRow); + + form.SetOptionalField("100"); + + Assert.AreEqual("1", form.CurrentRow.Fields[0].Required); + Assert.AreEqual("0", otherRow.Fields[0].Required); + break; + default: + throw new ArgumentOutOfRangeException(nameof(operation)); + } + + Assert.AreEqual(string.Empty, form.CurrentRow.RowAction); + Assert.AreEqual(RowObject.RowActions.Edit, otherRow.RowAction); + } + + [DataTestMethod] + [DataRow("Disabled")] + [DataRow("Enabled")] + [DataRow("Locked")] + [DataRow("Unlocked")] + [DataRow("Required")] + [DataRow("Optional")] + public void SetFields_FormObject_WithMixedRowMatches_OnlyAppliesToMatchingRows(string operation) + { + // Arrange + var form = new FormObject { CurrentRow = new RowObject { RowId = "1", RowAction = string.Empty }, MultipleIteration = true }; + var otherRow = new RowObject { RowId = "2", RowAction = string.Empty }; + + switch (operation) + { + case "Disabled": + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Enabled = "1" }); + otherRow.Fields.Add(new FieldObject { FieldNumber = "200", Enabled = "1" }); + form.OtherRows.Add(otherRow); + + form.SetDisabledFields(["100"]); + + Assert.AreEqual("0", form.CurrentRow.Fields[0].Enabled); + Assert.AreEqual("1", otherRow.Fields[0].Enabled); + break; + case "Enabled": + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Enabled = "0" }); + otherRow.Fields.Add(new FieldObject { FieldNumber = "200", Enabled = "0" }); + form.OtherRows.Add(otherRow); + + form.SetEnabledFields(["100"]); + + Assert.AreEqual("1", form.CurrentRow.Fields[0].Enabled); + Assert.AreEqual("0", otherRow.Fields[0].Enabled); + break; + case "Locked": + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Lock = "0" }); + otherRow.Fields.Add(new FieldObject { FieldNumber = "200", Lock = "0" }); + form.OtherRows.Add(otherRow); + + form.SetLockedFields(["100"]); + + Assert.AreEqual("1", form.CurrentRow.Fields[0].Lock); + Assert.AreEqual("0", otherRow.Fields[0].Lock); + break; + case "Unlocked": + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Lock = "1" }); + otherRow.Fields.Add(new FieldObject { FieldNumber = "200", Lock = "1" }); + form.OtherRows.Add(otherRow); + + form.SetUnlockedFields(["100"]); + + Assert.AreEqual("0", form.CurrentRow.Fields[0].Lock); + Assert.AreEqual("1", otherRow.Fields[0].Lock); + break; + case "Required": + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "0" }); + otherRow.Fields.Add(new FieldObject { FieldNumber = "200", Required = "0" }); + form.OtherRows.Add(otherRow); + + form.SetRequiredFields(["100"]); + + Assert.AreEqual("1", form.CurrentRow.Fields[0].Required); + Assert.AreEqual("0", otherRow.Fields[0].Required); + break; + case "Optional": + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "1" }); + otherRow.Fields.Add(new FieldObject { FieldNumber = "200", Required = "1" }); + form.OtherRows.Add(otherRow); + + form.SetOptionalFields(["100"]); + + Assert.AreEqual("0", form.CurrentRow.Fields[0].Required); + Assert.AreEqual("1", otherRow.Fields[0].Required); + break; + default: + throw new ArgumentOutOfRangeException(nameof(operation)); + } + + Assert.AreEqual(RowObject.RowActions.Edit, form.CurrentRow.RowAction); + Assert.AreEqual(string.Empty, otherRow.RowAction); + } + [TestMethod] public void GetFormId_FormObject_ReturnsFormId() { @@ -466,6 +640,134 @@ public void SetUnlockedFields_FormObject_WithMultipleIteration_UnlocksMatchingFi Assert.AreEqual("0", otherRow.Fields[1].Lock); } + [TestMethod] + public void SetRequiredField_FormObject_WithMultipleIteration_SetsFieldRequiredInAllRows() + { + // Arrange + var form = new FormObject { CurrentRow = new RowObject { RowId = "1", RowAction = string.Empty }, MultipleIteration = true }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "0" }); + var otherRow = new RowObject { RowId = "2", RowAction = string.Empty }; + otherRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "0" }); + form.OtherRows.Add(otherRow); + + // Act + form.SetRequiredField("100"); + + // Assert + Assert.AreEqual("1", form.CurrentRow.Fields[0].Required); + Assert.AreEqual("1", otherRow.Fields[0].Required); + Assert.AreEqual(RowObject.RowActions.Edit, form.CurrentRow.RowAction); + Assert.AreEqual(RowObject.RowActions.Edit, otherRow.RowAction); + } + + [TestMethod] + public void SetRequiredFields_FormObject_WithMultipleIteration_SetsMatchingFieldsInAllRows() + { + // Arrange + var form = new FormObject { CurrentRow = new RowObject { RowId = "1" }, MultipleIteration = true }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "0" }); + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "101", Required = "0" }); + + var otherRow = new RowObject { RowId = "2" }; + otherRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "0" }); + otherRow.Fields.Add(new FieldObject { FieldNumber = "101", Required = "0" }); + form.OtherRows.Add(otherRow); + + // Act + form.SetRequiredFields(["101"]); + + // Assert + Assert.AreEqual("0", form.CurrentRow.Fields[0].Required); + Assert.AreEqual("1", form.CurrentRow.Fields[1].Required); + Assert.AreEqual("0", otherRow.Fields[0].Required); + Assert.AreEqual("1", otherRow.Fields[1].Required); + } + + [TestMethod] + public void SetRequiredFields_FormObject_WithNoMatchingFields_ThrowsArgumentException() + { + // Arrange + var form = new FormObject { CurrentRow = new RowObject { RowId = "1" } }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "200", Required = "0" }); + + // Act / Assert + Assert.ThrowsException(() => form.SetRequiredFields(["100"])); + } + + [TestMethod] + public void SetRequiredFields_FormObject_WithNullCurrentRow_ReturnsOriginalForm() + { + // Arrange + var form = new FormObject { CurrentRow = null! }; + + // Act + var result = form.SetRequiredFields(["100"]); + + // Assert + Assert.AreSame(form, result); + } + + [TestMethod] + public void SetRequiredFields_FormObject_WithMultipleIterationFalse_DoesNotModifyOtherRows() + { + // Arrange + var form = new FormObject { CurrentRow = new RowObject { RowId = "1" }, MultipleIteration = false }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "0" }); + + var otherRow = new RowObject { RowId = "2" }; + otherRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "0" }); + form.OtherRows.Add(otherRow); + + // Act + form.SetRequiredFields(["100"]); + + // Assert + Assert.AreEqual("1", form.CurrentRow.Fields[0].Required); + Assert.AreEqual("0", otherRow.Fields[0].Required); + } + + [TestMethod] + public void SetOptionalFields_FormObject_WithMultipleIteration_SetsMatchingFieldsOptionalInAllRows() + { + // Arrange + var form = new FormObject { CurrentRow = new RowObject { RowId = "1" }, MultipleIteration = true }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "1" }); + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "101", Required = "1" }); + var otherRow = new RowObject { RowId = "2" }; + otherRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "1" }); + otherRow.Fields.Add(new FieldObject { FieldNumber = "101", Required = "1" }); + form.OtherRows.Add(otherRow); + + // Act + form.SetOptionalFields(["101"]); + + // Assert + Assert.AreEqual("1", form.CurrentRow.Fields[0].Required); + Assert.AreEqual("0", form.CurrentRow.Fields[1].Required); + Assert.AreEqual("1", otherRow.Fields[0].Required); + Assert.AreEqual("0", otherRow.Fields[1].Required); + } + + [TestMethod] + public void SetOptionalField_FormObject_WithMultipleIteration_SetsOptionalInAllRows() + { + // Arrange + var form = new FormObject { CurrentRow = new RowObject { RowId = "1", RowAction = string.Empty }, MultipleIteration = true }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "1" }); + var otherRow = new RowObject { RowId = "2", RowAction = string.Empty }; + otherRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "1" }); + form.OtherRows.Add(otherRow); + + // Act + form.SetOptionalField("100"); + + // Assert + Assert.AreEqual("0", form.CurrentRow.Fields[0].Required); + Assert.AreEqual("0", otherRow.Fields[0].Required); + Assert.AreEqual(RowObject.RowActions.Edit, form.CurrentRow.RowAction); + Assert.AreEqual(RowObject.RowActions.Edit, otherRow.RowAction); + } + [TestMethod] public void SetLockedField_FormObject_WithEmptyFieldNumber_ThrowsArgumentException() { diff --git a/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers.Tests/OptionObjectHelpers.OptionObject.Tests.cs b/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers.Tests/OptionObjectHelpers.OptionObject.Tests.cs index ba413a0..6f0857d 100644 --- a/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers.Tests/OptionObjectHelpers.OptionObject.Tests.cs +++ b/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers.Tests/OptionObjectHelpers.OptionObject.Tests.cs @@ -11,6 +11,8 @@ public class OptionObjectHelpersOptionObjectTests [DataRow("Enabled")] [DataRow("Locked")] [DataRow("Unlocked")] + [DataRow("Required")] + [DataRow("Optional")] public void SetField_OptionObject_WithNullFieldNumber_ThrowsArgumentNullException(string operation) { var optionObject = new OptionObject(); @@ -24,6 +26,8 @@ public void SetField_OptionObject_WithNullFieldNumber_ThrowsArgumentNullExceptio "Enabled" => () => optionObject.SetEnabledField(null!), "Locked" => () => optionObject.SetLockedField(null!), "Unlocked" => () => optionObject.SetUnlockedField(null!), + "Required" => () => optionObject.SetRequiredField(null!), + "Optional" => () => optionObject.SetOptionalField(null!), _ => throw new ArgumentOutOfRangeException(nameof(operation)) }; @@ -35,6 +39,8 @@ public void SetField_OptionObject_WithNullFieldNumber_ThrowsArgumentNullExceptio [DataRow("Enabled")] [DataRow("Locked")] [DataRow("Unlocked")] + [DataRow("Required")] + [DataRow("Optional")] public void SetField_OptionObject_WithEmptyFieldNumber_ThrowsArgumentException(string operation) { var optionObject = new OptionObject(); @@ -48,6 +54,8 @@ public void SetField_OptionObject_WithEmptyFieldNumber_ThrowsArgumentException(s "Enabled" => () => optionObject.SetEnabledField(string.Empty), "Locked" => () => optionObject.SetLockedField(string.Empty), "Unlocked" => () => optionObject.SetUnlockedField(string.Empty), + "Required" => () => optionObject.SetRequiredField(string.Empty), + "Optional" => () => optionObject.SetOptionalField(string.Empty), _ => throw new ArgumentOutOfRangeException(nameof(operation)) }; @@ -59,6 +67,8 @@ public void SetField_OptionObject_WithEmptyFieldNumber_ThrowsArgumentException(s [DataRow("Enabled")] [DataRow("Locked")] [DataRow("Unlocked")] + [DataRow("Required")] + [DataRow("Optional")] public void SetFields_OptionObject_WithMixedFormMatches_OnlyAppliesToMatchingForms(string operation) { var optionObject = new OptionObject(); @@ -111,6 +121,28 @@ public void SetFields_OptionObject_WithMixedFormMatches_OnlyAppliesToMatchingFor Assert.AreEqual("0", matchingForm.CurrentRow.Fields[0].Lock); Assert.AreEqual("1", nonMatchingForm.CurrentRow.Fields[0].Lock); break; + case "Required": + matchingForm.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "0" }); + nonMatchingForm.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "200", Required = "0" }); + optionObject.Forms.Add(matchingForm); + optionObject.Forms.Add(nonMatchingForm); + + optionObject.SetRequiredFields(new List { "100" }); + + Assert.AreEqual("1", matchingForm.CurrentRow.Fields[0].Required); + Assert.AreEqual("0", nonMatchingForm.CurrentRow.Fields[0].Required); + break; + case "Optional": + matchingForm.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "1" }); + nonMatchingForm.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "200", Required = "1" }); + optionObject.Forms.Add(matchingForm); + optionObject.Forms.Add(nonMatchingForm); + + optionObject.SetOptionalFields(new List { "100" }); + + Assert.AreEqual("0", matchingForm.CurrentRow.Fields[0].Required); + Assert.AreEqual("1", nonMatchingForm.CurrentRow.Fields[0].Required); + break; default: throw new ArgumentOutOfRangeException(nameof(operation)); } @@ -514,6 +546,117 @@ public void SetUnlockedField_OptionObject_WithNoMatchingField_ThrowsArgumentExce Assert.ThrowsException(() => optionObject.SetUnlockedField("100")); } + [TestMethod] + public void SetRequiredField_OptionObject_WithNoMatchingField_ThrowsArgumentException() + { + var optionObject = new OptionObject(); + var form = new FormObject { FormId = "1", CurrentRow = new RowObject { RowId = "1" } }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "200", Required = "0" }); + optionObject.Forms.Add(form); + + Assert.ThrowsException(() => optionObject.SetRequiredField("100")); + } + + [TestMethod] + public void SetOptionalField_OptionObject_WithNoMatchingField_ThrowsArgumentException() + { + var optionObject = new OptionObject(); + var form = new FormObject { FormId = "1", CurrentRow = new RowObject { RowId = "1" } }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "200", Required = "1" }); + optionObject.Forms.Add(form); + + Assert.ThrowsException(() => optionObject.SetOptionalField("100")); + } + + [TestMethod] + public void SetRequiredField_OptionObject_WithMatchingField_SetsRequired() + { + var optionObject = new OptionObject(); + var form = new FormObject { FormId = "1", CurrentRow = new RowObject { RowId = "1" } }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "0" }); + optionObject.Forms.Add(form); + + optionObject.SetRequiredField("100"); + + Assert.AreEqual("1", form.CurrentRow.Fields[0].Required); + } + + [TestMethod] + public void SetOptionalField_OptionObject_WithMatchingField_SetsOptional() + { + var optionObject = new OptionObject(); + var form = new FormObject { FormId = "1", CurrentRow = new RowObject { RowId = "1" } }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "1" }); + optionObject.Forms.Add(form); + + optionObject.SetOptionalField("100"); + + Assert.AreEqual("0", form.CurrentRow.Fields[0].Required); + } + + [DataTestMethod] + [DataRow("Required", "0", "0", "1", "0")] + [DataRow("Optional", "1", "1", "0", "1")] + public void SetSingleRequiredOptionalField_OptionObject_WithMixedFormMatches_OnlyMutatesMatchingForm( + string operation, + string initialTarget, + string initialNonTarget, + string expectedTarget, + string expectedNonTarget) + { + var optionObject = new OptionObject(); + var targetForm = new FormObject { FormId = "1", CurrentRow = new RowObject { RowId = "1" } }; + targetForm.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = initialTarget }); + + var nonTargetForm = new FormObject { FormId = "2", CurrentRow = new RowObject { RowId = "1" } }; + nonTargetForm.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "200", Required = initialNonTarget }); + + optionObject.Forms.Add(targetForm); + optionObject.Forms.Add(nonTargetForm); + + switch (operation) + { + case "Required": + optionObject.SetRequiredField("100"); + break; + case "Optional": + optionObject.SetOptionalField("100"); + break; + default: + Assert.Fail($"Unsupported operation '{operation}'"); + break; + } + + Assert.AreEqual(expectedTarget, targetForm.CurrentRow.Fields[0].Required); + Assert.AreEqual(expectedNonTarget, nonTargetForm.CurrentRow.Fields[0].Required); + } + + [TestMethod] + public void SetRequiredFields_OptionObject_WithFieldObjects_SetsRequired() + { + var optionObject = new OptionObject(); + var form = new FormObject { FormId = "1", CurrentRow = new RowObject { RowId = "1" } }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "0" }); + optionObject.Forms.Add(form); + + optionObject.SetRequiredFields(new List { new FieldObject { FieldNumber = "100" } }); + + Assert.AreEqual("1", form.CurrentRow.Fields[0].Required); + } + + [TestMethod] + public void SetOptionalFields_OptionObject_WithFieldObjects_SetsOptional() + { + var optionObject = new OptionObject(); + var form = new FormObject { FormId = "1", CurrentRow = new RowObject { RowId = "1" } }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "1" }); + optionObject.Forms.Add(form); + + optionObject.SetOptionalFields(new List { new FieldObject { FieldNumber = "100" } }); + + Assert.AreEqual("0", form.CurrentRow.Fields[0].Required); + } + [TestMethod] public void SetLockedFields_OptionObject_WithDuplicateFieldNumbers_LocksTargetField() { diff --git a/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers.Tests/OptionObjectHelpers.OptionObject2.Tests.cs b/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers.Tests/OptionObjectHelpers.OptionObject2.Tests.cs index 45e93d1..deeffd3 100644 --- a/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers.Tests/OptionObjectHelpers.OptionObject2.Tests.cs +++ b/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers.Tests/OptionObjectHelpers.OptionObject2.Tests.cs @@ -11,6 +11,8 @@ public class OptionObjectHelpersOptionObject2Tests [DataRow("Enabled")] [DataRow("Locked")] [DataRow("Unlocked")] + [DataRow("Required")] + [DataRow("Optional")] public void SetField_OptionObject2_WithNullFieldNumber_ThrowsArgumentNullException(string operation) { var optionObject = new OptionObject2(); @@ -24,6 +26,8 @@ public void SetField_OptionObject2_WithNullFieldNumber_ThrowsArgumentNullExcepti "Enabled" => () => optionObject.SetEnabledField(null!), "Locked" => () => optionObject.SetLockedField(null!), "Unlocked" => () => optionObject.SetUnlockedField(null!), + "Required" => () => optionObject.SetRequiredField(null!), + "Optional" => () => optionObject.SetOptionalField(null!), _ => throw new ArgumentOutOfRangeException(nameof(operation)) }; @@ -35,6 +39,8 @@ public void SetField_OptionObject2_WithNullFieldNumber_ThrowsArgumentNullExcepti [DataRow("Enabled")] [DataRow("Locked")] [DataRow("Unlocked")] + [DataRow("Required")] + [DataRow("Optional")] public void SetField_OptionObject2_WithEmptyFieldNumber_ThrowsArgumentException(string operation) { var optionObject = new OptionObject2(); @@ -48,6 +54,8 @@ public void SetField_OptionObject2_WithEmptyFieldNumber_ThrowsArgumentException( "Enabled" => () => optionObject.SetEnabledField(string.Empty), "Locked" => () => optionObject.SetLockedField(string.Empty), "Unlocked" => () => optionObject.SetUnlockedField(string.Empty), + "Required" => () => optionObject.SetRequiredField(string.Empty), + "Optional" => () => optionObject.SetOptionalField(string.Empty), _ => throw new ArgumentOutOfRangeException(nameof(operation)) }; @@ -59,6 +67,8 @@ public void SetField_OptionObject2_WithEmptyFieldNumber_ThrowsArgumentException( [DataRow("Enabled")] [DataRow("Locked")] [DataRow("Unlocked")] + [DataRow("Required")] + [DataRow("Optional")] public void SetFields_OptionObject2_WithMixedFormMatches_OnlyAppliesToMatchingForms(string operation) { var optionObject = new OptionObject2(); @@ -111,6 +121,28 @@ public void SetFields_OptionObject2_WithMixedFormMatches_OnlyAppliesToMatchingFo Assert.AreEqual("0", matchingForm.CurrentRow.Fields[0].Lock); Assert.AreEqual("1", nonMatchingForm.CurrentRow.Fields[0].Lock); break; + case "Required": + matchingForm.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "0" }); + nonMatchingForm.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "200", Required = "0" }); + optionObject.Forms.Add(matchingForm); + optionObject.Forms.Add(nonMatchingForm); + + optionObject.SetRequiredFields(new List { "100" }); + + Assert.AreEqual("1", matchingForm.CurrentRow.Fields[0].Required); + Assert.AreEqual("0", nonMatchingForm.CurrentRow.Fields[0].Required); + break; + case "Optional": + matchingForm.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "1" }); + nonMatchingForm.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "200", Required = "1" }); + optionObject.Forms.Add(matchingForm); + optionObject.Forms.Add(nonMatchingForm); + + optionObject.SetOptionalFields(new List { "100" }); + + Assert.AreEqual("0", matchingForm.CurrentRow.Fields[0].Required); + Assert.AreEqual("1", nonMatchingForm.CurrentRow.Fields[0].Required); + break; default: throw new ArgumentOutOfRangeException(nameof(operation)); } @@ -360,5 +392,116 @@ public void SetLockedField_OptionObject2_WithNoMatchingField_ThrowsArgumentExcep Assert.ThrowsException(() => optionObject.SetLockedField("100")); } + + [TestMethod] + public void SetRequiredField_OptionObject2_WithNoMatchingField_ThrowsArgumentException() + { + var optionObject = new OptionObject2(); + var form = new FormObject { FormId = "1", CurrentRow = new RowObject { RowId = "1" } }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "200", Required = "0" }); + optionObject.Forms.Add(form); + + Assert.ThrowsException(() => optionObject.SetRequiredField("100")); + } + + [TestMethod] + public void SetOptionalField_OptionObject2_WithNoMatchingField_ThrowsArgumentException() + { + var optionObject = new OptionObject2(); + var form = new FormObject { FormId = "1", CurrentRow = new RowObject { RowId = "1" } }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "200", Required = "1" }); + optionObject.Forms.Add(form); + + Assert.ThrowsException(() => optionObject.SetOptionalField("100")); + } + + [TestMethod] + public void SetRequiredField_OptionObject2_WithMatchingField_SetsRequired() + { + var optionObject = new OptionObject2(); + var form = new FormObject { FormId = "1", CurrentRow = new RowObject { RowId = "1" } }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "0" }); + optionObject.Forms.Add(form); + + optionObject.SetRequiredField("100"); + + Assert.AreEqual("1", form.CurrentRow.Fields[0].Required); + } + + [TestMethod] + public void SetOptionalField_OptionObject2_WithMatchingField_SetsOptional() + { + var optionObject = new OptionObject2(); + var form = new FormObject { FormId = "1", CurrentRow = new RowObject { RowId = "1" } }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "1" }); + optionObject.Forms.Add(form); + + optionObject.SetOptionalField("100"); + + Assert.AreEqual("0", form.CurrentRow.Fields[0].Required); + } + + [DataTestMethod] + [DataRow("Required", "0", "0", "1", "0")] + [DataRow("Optional", "1", "1", "0", "1")] + public void SetSingleRequiredOptionalField_OptionObject2_WithMixedFormMatches_OnlyMutatesMatchingForm( + string operation, + string initialTarget, + string initialNonTarget, + string expectedTarget, + string expectedNonTarget) + { + var optionObject = new OptionObject2(); + var targetForm = new FormObject { FormId = "1", CurrentRow = new RowObject { RowId = "1" } }; + targetForm.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = initialTarget }); + + var nonTargetForm = new FormObject { FormId = "2", CurrentRow = new RowObject { RowId = "1" } }; + nonTargetForm.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "200", Required = initialNonTarget }); + + optionObject.Forms.Add(targetForm); + optionObject.Forms.Add(nonTargetForm); + + switch (operation) + { + case "Required": + optionObject.SetRequiredField("100"); + break; + case "Optional": + optionObject.SetOptionalField("100"); + break; + default: + Assert.Fail($"Unsupported operation '{operation}'"); + break; + } + + Assert.AreEqual(expectedTarget, targetForm.CurrentRow.Fields[0].Required); + Assert.AreEqual(expectedNonTarget, nonTargetForm.CurrentRow.Fields[0].Required); + } + + [TestMethod] + public void SetRequiredFields_OptionObject2_WithFieldObjects_SetsRequired() + { + var optionObject = new OptionObject2(); + var form = new FormObject { FormId = "1", CurrentRow = new RowObject { RowId = "1" } }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "0" }); + optionObject.Forms.Add(form); + + optionObject.SetRequiredFields(new List { new FieldObject { FieldNumber = "100" } }); + + Assert.AreEqual("1", form.CurrentRow.Fields[0].Required); + } + + [TestMethod] + public void SetOptionalFields_OptionObject2_WithFieldObjects_SetsOptional() + { + var optionObject = new OptionObject2(); + var form = new FormObject { FormId = "1", CurrentRow = new RowObject { RowId = "1" } }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "1" }); + optionObject.Forms.Add(form); + + optionObject.SetOptionalFields(new List { new FieldObject { FieldNumber = "100" } }); + + Assert.AreEqual("0", form.CurrentRow.Fields[0].Required); + } } } diff --git a/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers.Tests/OptionObjectHelpers.OptionObject2015.Tests.cs b/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers.Tests/OptionObjectHelpers.OptionObject2015.Tests.cs index 9948e17..2487675 100644 --- a/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers.Tests/OptionObjectHelpers.OptionObject2015.Tests.cs +++ b/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers.Tests/OptionObjectHelpers.OptionObject2015.Tests.cs @@ -11,6 +11,8 @@ public class OptionObjectHelpersOptionObject2015Tests [DataRow("Enabled")] [DataRow("Locked")] [DataRow("Unlocked")] + [DataRow("Required")] + [DataRow("Optional")] public void SetField_OptionObject2015_WithNullFieldNumber_ThrowsArgumentNullException(string operation) { var optionObject = new OptionObject2015(); @@ -24,6 +26,8 @@ public void SetField_OptionObject2015_WithNullFieldNumber_ThrowsArgumentNullExce "Enabled" => () => optionObject.SetEnabledField(null!), "Locked" => () => optionObject.SetLockedField(null!), "Unlocked" => () => optionObject.SetUnlockedField(null!), + "Required" => () => optionObject.SetRequiredField(null!), + "Optional" => () => optionObject.SetOptionalField(null!), _ => throw new ArgumentOutOfRangeException(nameof(operation)) }; @@ -35,6 +39,8 @@ public void SetField_OptionObject2015_WithNullFieldNumber_ThrowsArgumentNullExce [DataRow("Enabled")] [DataRow("Locked")] [DataRow("Unlocked")] + [DataRow("Required")] + [DataRow("Optional")] public void SetField_OptionObject2015_WithEmptyFieldNumber_ThrowsArgumentException(string operation) { var optionObject = new OptionObject2015(); @@ -48,6 +54,8 @@ public void SetField_OptionObject2015_WithEmptyFieldNumber_ThrowsArgumentExcepti "Enabled" => () => optionObject.SetEnabledField(string.Empty), "Locked" => () => optionObject.SetLockedField(string.Empty), "Unlocked" => () => optionObject.SetUnlockedField(string.Empty), + "Required" => () => optionObject.SetRequiredField(string.Empty), + "Optional" => () => optionObject.SetOptionalField(string.Empty), _ => throw new ArgumentOutOfRangeException(nameof(operation)) }; @@ -59,6 +67,8 @@ public void SetField_OptionObject2015_WithEmptyFieldNumber_ThrowsArgumentExcepti [DataRow("Enabled")] [DataRow("Locked")] [DataRow("Unlocked")] + [DataRow("Required")] + [DataRow("Optional")] public void SetFields_OptionObject2015_WithMixedFormMatches_OnlyAppliesToMatchingForms(string operation) { var optionObject = new OptionObject2015(); @@ -111,6 +121,28 @@ public void SetFields_OptionObject2015_WithMixedFormMatches_OnlyAppliesToMatchin Assert.AreEqual("0", matchingForm.CurrentRow.Fields[0].Lock); Assert.AreEqual("1", nonMatchingForm.CurrentRow.Fields[0].Lock); break; + case "Required": + matchingForm.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "0" }); + nonMatchingForm.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "200", Required = "0" }); + optionObject.Forms.Add(matchingForm); + optionObject.Forms.Add(nonMatchingForm); + + optionObject.SetRequiredFields(new List { "100" }); + + Assert.AreEqual("1", matchingForm.CurrentRow.Fields[0].Required); + Assert.AreEqual("0", nonMatchingForm.CurrentRow.Fields[0].Required); + break; + case "Optional": + matchingForm.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "1" }); + nonMatchingForm.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "200", Required = "1" }); + optionObject.Forms.Add(matchingForm); + optionObject.Forms.Add(nonMatchingForm); + + optionObject.SetOptionalFields(new List { "100" }); + + Assert.AreEqual("0", matchingForm.CurrentRow.Fields[0].Required); + Assert.AreEqual("1", nonMatchingForm.CurrentRow.Fields[0].Required); + break; default: throw new ArgumentOutOfRangeException(nameof(operation)); } @@ -406,5 +438,116 @@ public void SetUnlockedField_OptionObject2015_WithNoMatchingField_ThrowsArgument Assert.ThrowsException(() => optionObject.SetUnlockedField("100")); } + + [TestMethod] + public void SetRequiredField_OptionObject2015_WithNoMatchingField_ThrowsArgumentException() + { + var optionObject = new OptionObject2015(); + var form = new FormObject { FormId = "1", CurrentRow = new RowObject { RowId = "1" } }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "200", Required = "0" }); + optionObject.Forms.Add(form); + + Assert.ThrowsException(() => optionObject.SetRequiredField("100")); + } + + [TestMethod] + public void SetOptionalField_OptionObject2015_WithNoMatchingField_ThrowsArgumentException() + { + var optionObject = new OptionObject2015(); + var form = new FormObject { FormId = "1", CurrentRow = new RowObject { RowId = "1" } }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "200", Required = "1" }); + optionObject.Forms.Add(form); + + Assert.ThrowsException(() => optionObject.SetOptionalField("100")); + } + + [TestMethod] + public void SetRequiredField_OptionObject2015_WithMatchingField_SetsRequired() + { + var optionObject = new OptionObject2015(); + var form = new FormObject { FormId = "1", CurrentRow = new RowObject { RowId = "1" } }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "0" }); + optionObject.Forms.Add(form); + + optionObject.SetRequiredField("100"); + + Assert.AreEqual("1", form.CurrentRow.Fields[0].Required); + } + + [TestMethod] + public void SetOptionalField_OptionObject2015_WithMatchingField_SetsOptional() + { + var optionObject = new OptionObject2015(); + var form = new FormObject { FormId = "1", CurrentRow = new RowObject { RowId = "1" } }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "1" }); + optionObject.Forms.Add(form); + + optionObject.SetOptionalField("100"); + + Assert.AreEqual("0", form.CurrentRow.Fields[0].Required); + } + + [DataTestMethod] + [DataRow("Required", "0", "0", "1", "0")] + [DataRow("Optional", "1", "1", "0", "1")] + public void SetSingleRequiredOptionalField_OptionObject2015_WithMixedFormMatches_OnlyMutatesMatchingForm( + string operation, + string initialTarget, + string initialNonTarget, + string expectedTarget, + string expectedNonTarget) + { + var optionObject = new OptionObject2015(); + var targetForm = new FormObject { FormId = "1", CurrentRow = new RowObject { RowId = "1" } }; + targetForm.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = initialTarget }); + + var nonTargetForm = new FormObject { FormId = "2", CurrentRow = new RowObject { RowId = "1" } }; + nonTargetForm.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "200", Required = initialNonTarget }); + + optionObject.Forms.Add(targetForm); + optionObject.Forms.Add(nonTargetForm); + + switch (operation) + { + case "Required": + optionObject.SetRequiredField("100"); + break; + case "Optional": + optionObject.SetOptionalField("100"); + break; + default: + Assert.Fail($"Unsupported operation '{operation}'"); + break; + } + + Assert.AreEqual(expectedTarget, targetForm.CurrentRow.Fields[0].Required); + Assert.AreEqual(expectedNonTarget, nonTargetForm.CurrentRow.Fields[0].Required); + } + + [TestMethod] + public void SetRequiredFields_OptionObject2015_WithFieldObjects_SetsRequired() + { + var optionObject = new OptionObject2015(); + var form = new FormObject { FormId = "1", CurrentRow = new RowObject { RowId = "1" } }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "0" }); + optionObject.Forms.Add(form); + + optionObject.SetRequiredFields(new List { new FieldObject { FieldNumber = "100" } }); + + Assert.AreEqual("1", form.CurrentRow.Fields[0].Required); + } + + [TestMethod] + public void SetOptionalFields_OptionObject2015_WithFieldObjects_SetsOptional() + { + var optionObject = new OptionObject2015(); + var form = new FormObject { FormId = "1", CurrentRow = new RowObject { RowId = "1" } }; + form.CurrentRow.Fields.Add(new FieldObject { FieldNumber = "100", Required = "1" }); + optionObject.Forms.Add(form); + + optionObject.SetOptionalFields(new List { new FieldObject { FieldNumber = "100" } }); + + Assert.AreEqual("0", form.CurrentRow.Fields[0].Required); + } } } diff --git a/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers.Tests/RowObjectHelpersTests.cs b/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers.Tests/RowObjectHelpersTests.cs index 5b4a34d..55e7e64 100644 --- a/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers.Tests/RowObjectHelpersTests.cs +++ b/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers.Tests/RowObjectHelpersTests.cs @@ -12,6 +12,8 @@ public class RowObjectHelpersTests [DataRow("Enabled")] [DataRow("Locked")] [DataRow("Unlocked")] + [DataRow("Required")] + [DataRow("Optional")] public void SetField_RowObject_WithNullFieldNumber_ThrowsArgumentNullException(string operation) { // Arrange @@ -25,6 +27,8 @@ public void SetField_RowObject_WithNullFieldNumber_ThrowsArgumentNullException(s "Enabled" => () => row.SetEnabledField(null!), "Locked" => () => row.SetLockedField(null!), "Unlocked" => () => row.SetUnlockedField(null!), + "Required" => () => row.SetRequiredField(null!), + "Optional" => () => row.SetOptionalField(null!), _ => throw new ArgumentOutOfRangeException(nameof(operation)) }; @@ -37,6 +41,8 @@ public void SetField_RowObject_WithNullFieldNumber_ThrowsArgumentNullException(s [DataRow("Enabled")] [DataRow("Locked")] [DataRow("Unlocked")] + [DataRow("Required")] + [DataRow("Optional")] public void SetField_RowObject_WithEmptyFieldNumber_ThrowsArgumentException(string operation) { // Arrange @@ -50,6 +56,8 @@ public void SetField_RowObject_WithEmptyFieldNumber_ThrowsArgumentException(stri "Enabled" => () => row.SetEnabledField(string.Empty), "Locked" => () => row.SetLockedField(string.Empty), "Unlocked" => () => row.SetUnlockedField(string.Empty), + "Required" => () => row.SetRequiredField(string.Empty), + "Optional" => () => row.SetOptionalField(string.Empty), _ => throw new ArgumentOutOfRangeException(nameof(operation)) }; @@ -508,6 +516,124 @@ public void SetEnabledFields_RowObject_WithFieldNumbers_EnablesMatchingFields() Assert.AreEqual("1", row.Fields[1].Enabled); } + [TestMethod] + public void SetRequiredField_RowObject_WithExistingField_SetsRequiredAndRowAction() + { + // Arrange + var row = new RowObject { RowAction = string.Empty }; + row.Fields.Add(new FieldObject { FieldNumber = "100", Required = "0" }); + + // Act + row.SetRequiredField("100"); + + // Assert + Assert.AreEqual("1", row.Fields[0].Required); + Assert.AreEqual(RowObject.RowActions.Edit, row.RowAction); + } + + [DataTestMethod] + [DataRow("", RowObject.RowActions.Edit)] + [DataRow(RowObject.RowActions.Add, RowObject.RowActions.Add)] + [DataRow(RowObject.RowActions.Delete, RowObject.RowActions.Delete)] + [DataRow(RowObject.RowActions.Edit, RowObject.RowActions.Edit)] + public void SetRequiredField_RowObject_WithDifferentInitialRowActions_AppliesExpectedRowAction( + string initialRowAction, + string expectedRowAction) + { + // Arrange + var row = new RowObject { RowAction = initialRowAction }; + row.Fields.Add(new FieldObject { FieldNumber = "100", Required = "0" }); + + // Act + row.SetRequiredField("100"); + + // Assert + Assert.AreEqual("1", row.Fields[0].Required); + Assert.AreEqual(expectedRowAction, row.RowAction); + } + + [TestMethod] + public void SetRequiredField_RowObject_WhenAlreadyRequired_DoesNotSetRowAction() + { + // Arrange + var row = new RowObject { RowAction = "" }; + row.Fields.Add(new FieldObject { FieldNumber = "100", Required = "1" }); + + // Act + row.SetRequiredField("100"); + + // Assert + Assert.AreEqual("1", row.Fields[0].Required); + Assert.AreEqual("", row.RowAction); + } + + [TestMethod] + public void SetOptionalFields_RowObject_WithFieldNumbers_SetsMatchingFieldsOptional() + { + // Arrange + var row = new RowObject(); + row.Fields.Add(new FieldObject { FieldNumber = "100", Required = "1" }); + row.Fields.Add(new FieldObject { FieldNumber = "101", Required = "1" }); + + // Act + row.SetOptionalFields(["101"]); + + // Assert + Assert.AreEqual("1", row.Fields[0].Required); + Assert.AreEqual("0", row.Fields[1].Required); + } + + [TestMethod] + public void SetOptionalField_RowObject_WithExistingRequiredField_SetsOptionalAndRowAction() + { + // Arrange + var row = new RowObject { RowAction = string.Empty }; + row.Fields.Add(new FieldObject { FieldNumber = "100", Required = "1" }); + + // Act + row.SetOptionalField("100"); + + // Assert + Assert.AreEqual("0", row.Fields[0].Required); + Assert.AreEqual(RowObject.RowActions.Edit, row.RowAction); + } + + [DataTestMethod] + [DataRow("", RowObject.RowActions.Edit)] + [DataRow(RowObject.RowActions.Add, RowObject.RowActions.Add)] + [DataRow(RowObject.RowActions.Delete, RowObject.RowActions.Delete)] + [DataRow(RowObject.RowActions.Edit, RowObject.RowActions.Edit)] + public void SetOptionalField_RowObject_WithDifferentInitialRowActions_AppliesExpectedRowAction( + string initialRowAction, + string expectedRowAction) + { + // Arrange + var row = new RowObject { RowAction = initialRowAction }; + row.Fields.Add(new FieldObject { FieldNumber = "100", Required = "1" }); + + // Act + row.SetOptionalField("100"); + + // Assert + Assert.AreEqual("0", row.Fields[0].Required); + Assert.AreEqual(expectedRowAction, row.RowAction); + } + + [TestMethod] + public void SetOptionalField_RowObject_WhenAlreadyOptional_DoesNotSetRowAction() + { + // Arrange + var row = new RowObject { RowAction = "" }; + row.Fields.Add(new FieldObject { FieldNumber = "100", Required = "0" }); + + // Act + row.SetOptionalField("100"); + + // Assert + Assert.AreEqual("0", row.Fields[0].Required); + Assert.AreEqual("", row.RowAction); + } + [TestMethod] public void SetEnabledFields_RowObject_WithDeleteRowAction_PreservesDelete() { diff --git a/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers/FormObjectHelpers.cs b/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers/FormObjectHelpers.cs index 659c456..0e1da94 100644 --- a/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers/FormObjectHelpers.cs +++ b/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers/FormObjectHelpers.cs @@ -329,11 +329,14 @@ public static bool IsRowPresent(this FormObject formObject, string rowId) if (!hasFieldInForm) throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumber)); - formObject.CurrentRow.SetDisabledField(fieldNumber); + if (formObject.CurrentRow.IsFieldPresent(fieldNumber)) + { + formObject.CurrentRow.SetDisabledField(fieldNumber); + } if (formObject.MultipleIteration && formObject.HasOtherRows()) { - foreach (var row in formObject.OtherRows) + foreach (var row in formObject.OtherRows.Where(r => r.IsFieldPresent(fieldNumber))) { row.SetDisabledField(fieldNumber); } @@ -361,13 +364,21 @@ public static bool IsRowPresent(this FormObject formObject, string rowId) if (!hasAnyField) throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumbers)); - formObject.CurrentRow.SetDisabledFields(fieldsToSet); + var currentRowFieldNumbers = fieldsToSet.Where(formObject.CurrentRow.IsFieldPresent).ToList(); + if (currentRowFieldNumbers.Count > 0) + { + formObject.CurrentRow.SetDisabledFields(currentRowFieldNumbers); + } if (formObject.MultipleIteration && formObject.HasOtherRows()) { foreach (var row in formObject.OtherRows) { - row.SetDisabledFields(fieldsToSet); + var rowFieldNumbers = fieldsToSet.Where(row.IsFieldPresent).ToList(); + if (rowFieldNumbers.Count > 0) + { + row.SetDisabledFields(rowFieldNumbers); + } } } @@ -393,11 +404,14 @@ public static bool IsRowPresent(this FormObject formObject, string rowId) if (!hasFieldInForm) throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumber)); - formObject.CurrentRow.SetEnabledField(fieldNumber); + if (formObject.CurrentRow.IsFieldPresent(fieldNumber)) + { + formObject.CurrentRow.SetEnabledField(fieldNumber); + } if (formObject.MultipleIteration && formObject.HasOtherRows()) { - foreach (var row in formObject.OtherRows) + foreach (var row in formObject.OtherRows.Where(r => r.IsFieldPresent(fieldNumber))) { row.SetEnabledField(fieldNumber); } @@ -425,13 +439,21 @@ public static bool IsRowPresent(this FormObject formObject, string rowId) if (!hasAnyField) throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumbers)); - formObject.CurrentRow.SetEnabledFields(fieldsToSet); + var currentRowFieldNumbers = fieldsToSet.Where(formObject.CurrentRow.IsFieldPresent).ToList(); + if (currentRowFieldNumbers.Count > 0) + { + formObject.CurrentRow.SetEnabledFields(currentRowFieldNumbers); + } if (formObject.MultipleIteration && formObject.HasOtherRows()) { foreach (var row in formObject.OtherRows) { - row.SetEnabledFields(fieldsToSet); + var rowFieldNumbers = fieldsToSet.Where(row.IsFieldPresent).ToList(); + if (rowFieldNumbers.Count > 0) + { + row.SetEnabledFields(rowFieldNumbers); + } } } @@ -457,11 +479,14 @@ public static bool IsRowPresent(this FormObject formObject, string rowId) if (!hasFieldInForm) throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumber)); - formObject.CurrentRow.SetLockedField(fieldNumber); + if (formObject.CurrentRow.IsFieldPresent(fieldNumber)) + { + formObject.CurrentRow.SetLockedField(fieldNumber); + } if (formObject.MultipleIteration && formObject.HasOtherRows()) { - foreach (var row in formObject.OtherRows) + foreach (var row in formObject.OtherRows.Where(r => r.IsFieldPresent(fieldNumber))) { row.SetLockedField(fieldNumber); } @@ -489,13 +514,21 @@ public static bool IsRowPresent(this FormObject formObject, string rowId) if (!hasAnyField) throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumbers)); - formObject.CurrentRow.SetLockedFields(fieldsToSet); + var currentRowFieldNumbers = fieldsToSet.Where(formObject.CurrentRow.IsFieldPresent).ToList(); + if (currentRowFieldNumbers.Count > 0) + { + formObject.CurrentRow.SetLockedFields(currentRowFieldNumbers); + } if (formObject.MultipleIteration && formObject.HasOtherRows()) { foreach (var row in formObject.OtherRows) { - row.SetLockedFields(fieldsToSet); + var rowFieldNumbers = fieldsToSet.Where(row.IsFieldPresent).ToList(); + if (rowFieldNumbers.Count > 0) + { + row.SetLockedFields(rowFieldNumbers); + } } } @@ -521,11 +554,14 @@ public static bool IsRowPresent(this FormObject formObject, string rowId) if (!hasFieldInForm) throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumber)); - formObject.CurrentRow.SetUnlockedField(fieldNumber); + if (formObject.CurrentRow.IsFieldPresent(fieldNumber)) + { + formObject.CurrentRow.SetUnlockedField(fieldNumber); + } if (formObject.MultipleIteration && formObject.HasOtherRows()) { - foreach (var row in formObject.OtherRows) + foreach (var row in formObject.OtherRows.Where(r => r.IsFieldPresent(fieldNumber))) { row.SetUnlockedField(fieldNumber); } @@ -553,13 +589,171 @@ public static bool IsRowPresent(this FormObject formObject, string rowId) if (!hasAnyField) throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumbers)); - formObject.CurrentRow.SetUnlockedFields(fieldsToSet); + var currentRowFieldNumbers = fieldsToSet.Where(formObject.CurrentRow.IsFieldPresent).ToList(); + if (currentRowFieldNumbers.Count > 0) + { + formObject.CurrentRow.SetUnlockedFields(currentRowFieldNumbers); + } + + if (formObject.MultipleIteration && formObject.HasOtherRows()) + { + foreach (var row in formObject.OtherRows) + { + var rowFieldNumbers = fieldsToSet.Where(row.IsFieldPresent).ToList(); + if (rowFieldNumbers.Count > 0) + { + row.SetUnlockedFields(rowFieldNumbers); + } + } + } + + return formObject; + } + + /// + /// Marks a in a as required by field number. + /// + /// The FormObject to modify. + /// The field number to mark as required. + /// The modified FormObject. + public static FormObject? SetRequiredField(this FormObject formObject, string fieldNumber) + { + ArgumentGuards.ValidateFieldNumber(fieldNumber, nameof(fieldNumber)); + + if (formObject == null || formObject.CurrentRow == null) + return formObject; + + var hasFieldInForm = formObject.CurrentRow.IsFieldPresent(fieldNumber) + || (formObject.MultipleIteration && formObject.HasOtherRows() && formObject.OtherRows.Any(r => r.IsFieldPresent(fieldNumber))); + + if (!hasFieldInForm) + throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumber)); + + if (formObject.CurrentRow.IsFieldPresent(fieldNumber)) + { + formObject.CurrentRow.SetRequiredField(fieldNumber); + } + + if (formObject.MultipleIteration && formObject.HasOtherRows()) + { + foreach (var row in formObject.OtherRows.Where(r => r.IsFieldPresent(fieldNumber))) + { + row.SetRequiredField(fieldNumber); + } + } + + return formObject; + } + + /// + /// Marks instances in a as required by field numbers. + /// + /// The FormObject to modify. + /// The field numbers to mark as required. + /// The modified FormObject. + public static FormObject? SetRequiredFields(this FormObject formObject, List? fieldNumbers) + { + var fieldsToSet = ArgumentGuards.ValidateAndNormalizeFieldNumbers(fieldNumbers, nameof(fieldNumbers)); + + if (formObject == null || formObject.CurrentRow == null) + return formObject; + + var hasAnyField = fieldsToSet.Any(f => formObject.CurrentRow.IsFieldPresent(f)) + || (formObject.MultipleIteration && formObject.HasOtherRows() && fieldsToSet.Any(f => formObject.OtherRows.Any(r => r.IsFieldPresent(f)))); + + if (!hasAnyField) + throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumbers)); + + var currentRowFieldNumbers = fieldsToSet.Where(formObject.CurrentRow.IsFieldPresent).ToList(); + if (currentRowFieldNumbers.Count > 0) + { + formObject.CurrentRow.SetRequiredFields(currentRowFieldNumbers); + } + + if (formObject.MultipleIteration && formObject.HasOtherRows()) + { + foreach (var row in formObject.OtherRows) + { + var rowFieldNumbers = fieldsToSet.Where(row.IsFieldPresent).ToList(); + if (rowFieldNumbers.Count > 0) + { + row.SetRequiredFields(rowFieldNumbers); + } + } + } + + return formObject; + } + + /// + /// Marks a in a as optional by field number. + /// + /// The FormObject to modify. + /// The field number to mark as optional. + /// The modified FormObject. + public static FormObject? SetOptionalField(this FormObject formObject, string fieldNumber) + { + ArgumentGuards.ValidateFieldNumber(fieldNumber, nameof(fieldNumber)); + + if (formObject == null || formObject.CurrentRow == null) + return formObject; + + var hasFieldInForm = formObject.CurrentRow.IsFieldPresent(fieldNumber) + || (formObject.MultipleIteration && formObject.HasOtherRows() && formObject.OtherRows.Any(r => r.IsFieldPresent(fieldNumber))); + + if (!hasFieldInForm) + throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumber)); + + if (formObject.CurrentRow.IsFieldPresent(fieldNumber)) + { + formObject.CurrentRow.SetOptionalField(fieldNumber); + } + + if (formObject.MultipleIteration && formObject.HasOtherRows()) + { + foreach (var row in formObject.OtherRows.Where(r => r.IsFieldPresent(fieldNumber))) + { + row.SetOptionalField(fieldNumber); + } + } + + return formObject; + } + + /// + /// Marks instances in a as optional by field numbers. + /// + /// The FormObject to modify. + /// The field numbers to mark as optional. + /// The modified FormObject. + public static FormObject? SetOptionalFields(this FormObject formObject, List? fieldNumbers) + { + var fieldsToSet = ArgumentGuards.ValidateAndNormalizeFieldNumbers(fieldNumbers, nameof(fieldNumbers)); + + if (formObject == null || formObject.CurrentRow == null) + return formObject; + + var hasAnyField = fieldsToSet.Any(f => formObject.CurrentRow.IsFieldPresent(f)) + || (formObject.MultipleIteration && formObject.HasOtherRows() && fieldsToSet.Any(f => formObject.OtherRows.Any(r => r.IsFieldPresent(f)))); + + if (!hasAnyField) + throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumbers)); + + var currentRowFieldNumbers = fieldsToSet.Where(formObject.CurrentRow.IsFieldPresent).ToList(); + if (currentRowFieldNumbers.Count > 0) + { + formObject.CurrentRow.SetOptionalFields(currentRowFieldNumbers); + } if (formObject.MultipleIteration && formObject.HasOtherRows()) { foreach (var row in formObject.OtherRows) { - row.SetUnlockedFields(fieldsToSet); + var rowFieldNumbers = fieldsToSet.Where(row.IsFieldPresent).ToList(); + if (rowFieldNumbers.Count > 0) + { + row.SetOptionalFields(rowFieldNumbers); + } } } diff --git a/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers/OptionObject2015Helpers.cs b/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers/OptionObject2015Helpers.cs index e75da4d..a71c0c6 100644 --- a/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers/OptionObject2015Helpers.cs +++ b/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers/OptionObject2015Helpers.cs @@ -355,5 +355,149 @@ public static bool HasError(this OptionObject2015 optionObject) return optionObject; } + + /// + /// Marks a in an as required by field number. + /// + /// The OptionObject2015 to modify. + /// The field number to mark as required. + /// The modified OptionObject2015. + public static OptionObject2015? SetRequiredField(this OptionObject2015 optionObject, string fieldNumber) + { + ArgumentGuards.ValidateFieldNumber(fieldNumber, nameof(fieldNumber)); + + if (optionObject == null || optionObject.Forms == null) + return optionObject; + + if (!optionObject.Forms.Any(f => f.IsFieldPresent(fieldNumber))) + throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumber)); + + foreach (var form in optionObject.Forms) + { + if (!form.IsFieldPresent(fieldNumber)) + continue; + + form.SetRequiredField(fieldNumber); + } + + return optionObject; + } + + /// + /// Marks instances in an as required. + /// + /// The OptionObject2015 to modify. + /// The field objects to mark as required. + /// The modified OptionObject2015. + public static OptionObject2015? SetRequiredFields(this OptionObject2015 optionObject, List? fieldObjects) + { + var fieldNumbers = ArgumentGuards.ValidateAndGetFieldNumbers(fieldObjects, nameof(fieldObjects)); + + return optionObject.SetRequiredFields(fieldNumbers); + } + + /// + /// Marks instances in an as required by field numbers. + /// + /// The OptionObject2015 to modify. + /// The field numbers to mark as required. + /// The modified OptionObject2015. + public static OptionObject2015? SetRequiredFields(this OptionObject2015 optionObject, List? fieldNumbers) + { + var fieldsToSet = ArgumentGuards.ValidateAndNormalizeFieldNumbers(fieldNumbers, nameof(fieldNumbers)); + + if (optionObject == null || optionObject.Forms == null) + return optionObject; + + fieldsToSet = fieldsToSet + .Where(f => optionObject.Forms.Any(form => form.IsFieldPresent(f))) + .ToList(); + + if (fieldsToSet.Count == 0) + throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumbers)); + + foreach (var form in optionObject.Forms) + { + var formFieldNumbers = fieldsToSet.Where(form.IsFieldPresent).ToList(); + if (formFieldNumbers.Count == 0) + continue; + + form.SetRequiredFields(formFieldNumbers); + } + + return optionObject; + } + + /// + /// Marks a in an as optional by field number. + /// + /// The OptionObject2015 to modify. + /// The field number to mark as optional. + /// The modified OptionObject2015. + public static OptionObject2015? SetOptionalField(this OptionObject2015 optionObject, string fieldNumber) + { + ArgumentGuards.ValidateFieldNumber(fieldNumber, nameof(fieldNumber)); + + if (optionObject == null || optionObject.Forms == null) + return optionObject; + + if (!optionObject.Forms.Any(f => f.IsFieldPresent(fieldNumber))) + throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumber)); + + foreach (var form in optionObject.Forms) + { + if (!form.IsFieldPresent(fieldNumber)) + continue; + + form.SetOptionalField(fieldNumber); + } + + return optionObject; + } + + /// + /// Marks instances in an as optional. + /// + /// The OptionObject2015 to modify. + /// The field objects to mark as optional. + /// The modified OptionObject2015. + public static OptionObject2015? SetOptionalFields(this OptionObject2015 optionObject, List? fieldObjects) + { + var fieldNumbers = ArgumentGuards.ValidateAndGetFieldNumbers(fieldObjects, nameof(fieldObjects)); + + return optionObject.SetOptionalFields(fieldNumbers); + } + + /// + /// Marks instances in an as optional by field numbers. + /// + /// The OptionObject2015 to modify. + /// The field numbers to mark as optional. + /// The modified OptionObject2015. + public static OptionObject2015? SetOptionalFields(this OptionObject2015 optionObject, List? fieldNumbers) + { + var fieldsToSet = ArgumentGuards.ValidateAndNormalizeFieldNumbers(fieldNumbers, nameof(fieldNumbers)); + + if (optionObject == null || optionObject.Forms == null) + return optionObject; + + fieldsToSet = fieldsToSet + .Where(f => optionObject.Forms.Any(form => form.IsFieldPresent(f))) + .ToList(); + + if (fieldsToSet.Count == 0) + throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumbers)); + + foreach (var form in optionObject.Forms) + { + var formFieldNumbers = fieldsToSet.Where(form.IsFieldPresent).ToList(); + if (formFieldNumbers.Count == 0) + continue; + + form.SetOptionalFields(formFieldNumbers); + } + + return optionObject; + } } } diff --git a/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers/OptionObject2Helpers.cs b/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers/OptionObject2Helpers.cs index cf0eb62..fca536a 100644 --- a/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers/OptionObject2Helpers.cs +++ b/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers/OptionObject2Helpers.cs @@ -335,5 +335,149 @@ public static bool HasError(this OptionObject2 optionObject) return optionObject; } + + /// + /// Marks a in an as required by field number. + /// + /// The OptionObject2 to modify. + /// The field number to mark as required. + /// The modified OptionObject2. + public static OptionObject2? SetRequiredField(this OptionObject2 optionObject, string fieldNumber) + { + ArgumentGuards.ValidateFieldNumber(fieldNumber, nameof(fieldNumber)); + + if (optionObject == null || optionObject.Forms == null) + return optionObject; + + if (!optionObject.Forms.Any(f => f.IsFieldPresent(fieldNumber))) + throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumber)); + + foreach (var form in optionObject.Forms) + { + if (!form.IsFieldPresent(fieldNumber)) + continue; + + form.SetRequiredField(fieldNumber); + } + + return optionObject; + } + + /// + /// Marks instances in an as required. + /// + /// The OptionObject2 to modify. + /// The field objects to mark as required. + /// The modified OptionObject2. + public static OptionObject2? SetRequiredFields(this OptionObject2 optionObject, List? fieldObjects) + { + var fieldNumbers = ArgumentGuards.ValidateAndGetFieldNumbers(fieldObjects, nameof(fieldObjects)); + + return optionObject.SetRequiredFields(fieldNumbers); + } + + /// + /// Marks instances in an as required by field numbers. + /// + /// The OptionObject2 to modify. + /// The field numbers to mark as required. + /// The modified OptionObject2. + public static OptionObject2? SetRequiredFields(this OptionObject2 optionObject, List? fieldNumbers) + { + var fieldsToSet = ArgumentGuards.ValidateAndNormalizeFieldNumbers(fieldNumbers, nameof(fieldNumbers)); + + if (optionObject == null || optionObject.Forms == null) + return optionObject; + + fieldsToSet = fieldsToSet + .Where(f => optionObject.Forms.Any(form => form.IsFieldPresent(f))) + .ToList(); + + if (fieldsToSet.Count == 0) + throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumbers)); + + foreach (var form in optionObject.Forms) + { + var formFieldNumbers = fieldsToSet.Where(form.IsFieldPresent).ToList(); + if (formFieldNumbers.Count == 0) + continue; + + form.SetRequiredFields(formFieldNumbers); + } + + return optionObject; + } + + /// + /// Marks a in an as optional by field number. + /// + /// The OptionObject2 to modify. + /// The field number to mark as optional. + /// The modified OptionObject2. + public static OptionObject2? SetOptionalField(this OptionObject2 optionObject, string fieldNumber) + { + ArgumentGuards.ValidateFieldNumber(fieldNumber, nameof(fieldNumber)); + + if (optionObject == null || optionObject.Forms == null) + return optionObject; + + if (!optionObject.Forms.Any(f => f.IsFieldPresent(fieldNumber))) + throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumber)); + + foreach (var form in optionObject.Forms) + { + if (!form.IsFieldPresent(fieldNumber)) + continue; + + form.SetOptionalField(fieldNumber); + } + + return optionObject; + } + + /// + /// Marks instances in an as optional. + /// + /// The OptionObject2 to modify. + /// The field objects to mark as optional. + /// The modified OptionObject2. + public static OptionObject2? SetOptionalFields(this OptionObject2 optionObject, List? fieldObjects) + { + var fieldNumbers = ArgumentGuards.ValidateAndGetFieldNumbers(fieldObjects, nameof(fieldObjects)); + + return optionObject.SetOptionalFields(fieldNumbers); + } + + /// + /// Marks instances in an as optional by field numbers. + /// + /// The OptionObject2 to modify. + /// The field numbers to mark as optional. + /// The modified OptionObject2. + public static OptionObject2? SetOptionalFields(this OptionObject2 optionObject, List? fieldNumbers) + { + var fieldsToSet = ArgumentGuards.ValidateAndNormalizeFieldNumbers(fieldNumbers, nameof(fieldNumbers)); + + if (optionObject == null || optionObject.Forms == null) + return optionObject; + + fieldsToSet = fieldsToSet + .Where(f => optionObject.Forms.Any(form => form.IsFieldPresent(f))) + .ToList(); + + if (fieldsToSet.Count == 0) + throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumbers)); + + foreach (var form in optionObject.Forms) + { + var formFieldNumbers = fieldsToSet.Where(form.IsFieldPresent).ToList(); + if (formFieldNumbers.Count == 0) + continue; + + form.SetOptionalFields(formFieldNumbers); + } + + return optionObject; + } } } diff --git a/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers/OptionObjectHelpers.cs b/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers/OptionObjectHelpers.cs index 697cd0c..892ff88 100644 --- a/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers/OptionObjectHelpers.cs +++ b/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers/OptionObjectHelpers.cs @@ -505,5 +505,149 @@ public static bool IsFieldRequired(this OptionObject optionObject, string fieldN return optionObject; } + + /// + /// Marks a in an as required by field number. + /// + /// The OptionObject to modify. + /// The field number to mark as required. + /// The modified OptionObject. + public static OptionObject? SetRequiredField(this OptionObject optionObject, string fieldNumber) + { + ArgumentGuards.ValidateFieldNumber(fieldNumber, nameof(fieldNumber)); + + if (optionObject == null || optionObject.Forms == null) + return optionObject; + + if (!optionObject.Forms.Any(f => f.IsFieldPresent(fieldNumber))) + throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumber)); + + foreach (var form in optionObject.Forms) + { + if (!form.IsFieldPresent(fieldNumber)) + continue; + + form.SetRequiredField(fieldNumber); + } + + return optionObject; + } + + /// + /// Marks instances in an as required. + /// + /// The OptionObject to modify. + /// The field objects to mark as required. + /// The modified OptionObject. + public static OptionObject? SetRequiredFields(this OptionObject optionObject, List? fieldObjects) + { + var fieldNumbers = ArgumentGuards.ValidateAndGetFieldNumbers(fieldObjects, nameof(fieldObjects)); + + return optionObject.SetRequiredFields(fieldNumbers); + } + + /// + /// Marks instances in an as required by field numbers. + /// + /// The OptionObject to modify. + /// The field numbers to mark as required. + /// The modified OptionObject. + public static OptionObject? SetRequiredFields(this OptionObject optionObject, List? fieldNumbers) + { + var fieldsToSet = ArgumentGuards.ValidateAndNormalizeFieldNumbers(fieldNumbers, nameof(fieldNumbers)); + + if (optionObject == null || optionObject.Forms == null) + return optionObject; + + fieldsToSet = fieldsToSet + .Where(f => optionObject.Forms.Any(form => form.IsFieldPresent(f))) + .ToList(); + + if (fieldsToSet.Count == 0) + throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumbers)); + + foreach (var form in optionObject.Forms) + { + var formFieldNumbers = fieldsToSet.Where(form.IsFieldPresent).ToList(); + if (formFieldNumbers.Count == 0) + continue; + + form.SetRequiredFields(formFieldNumbers); + } + + return optionObject; + } + + /// + /// Marks a in an as optional by field number. + /// + /// The OptionObject to modify. + /// The field number to mark as optional. + /// The modified OptionObject. + public static OptionObject? SetOptionalField(this OptionObject optionObject, string fieldNumber) + { + ArgumentGuards.ValidateFieldNumber(fieldNumber, nameof(fieldNumber)); + + if (optionObject == null || optionObject.Forms == null) + return optionObject; + + if (!optionObject.Forms.Any(f => f.IsFieldPresent(fieldNumber))) + throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumber)); + + foreach (var form in optionObject.Forms) + { + if (!form.IsFieldPresent(fieldNumber)) + continue; + + form.SetOptionalField(fieldNumber); + } + + return optionObject; + } + + /// + /// Marks instances in an as optional. + /// + /// The OptionObject to modify. + /// The field objects to mark as optional. + /// The modified OptionObject. + public static OptionObject? SetOptionalFields(this OptionObject optionObject, List? fieldObjects) + { + var fieldNumbers = ArgumentGuards.ValidateAndGetFieldNumbers(fieldObjects, nameof(fieldObjects)); + + return optionObject.SetOptionalFields(fieldNumbers); + } + + /// + /// Marks instances in an as optional by field numbers. + /// + /// The OptionObject to modify. + /// The field numbers to mark as optional. + /// The modified OptionObject. + public static OptionObject? SetOptionalFields(this OptionObject optionObject, List? fieldNumbers) + { + var fieldsToSet = ArgumentGuards.ValidateAndNormalizeFieldNumbers(fieldNumbers, nameof(fieldNumbers)); + + if (optionObject == null || optionObject.Forms == null) + return optionObject; + + fieldsToSet = fieldsToSet + .Where(f => optionObject.Forms.Any(form => form.IsFieldPresent(f))) + .ToList(); + + if (fieldsToSet.Count == 0) + throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumbers)); + + foreach (var form in optionObject.Forms) + { + var formFieldNumbers = fieldsToSet.Where(form.IsFieldPresent).ToList(); + if (formFieldNumbers.Count == 0) + continue; + + form.SetOptionalFields(formFieldNumbers); + } + + return optionObject; + } } } diff --git a/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers/RowObjectHelpers.cs b/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers/RowObjectHelpers.cs index 6d4d623..b735643 100644 --- a/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers/RowObjectHelpers.cs +++ b/dotnet/RarelySimple.AvatarScriptLink.Objects.Helpers/RowObjectHelpers.cs @@ -432,6 +432,124 @@ public static bool IsFieldRequired(this RowObject rowObject, string fieldNumber) return rowObject; } + /// + /// Marks a in a as required by field number. + /// + /// The RowObject to modify. + /// The field number to mark as required. + /// The modified RowObject. + public static RowObject? SetRequiredField(this RowObject rowObject, string fieldNumber) + { + ArgumentGuards.ValidateFieldNumber(fieldNumber, nameof(fieldNumber)); + + if (rowObject == null || rowObject.Fields == null) + return rowObject; + + var field = rowObject.Fields.FirstOrDefault(f => f.FieldNumber == fieldNumber); + if (field == null) + throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumber)); + + var changed = !field.IsRequired(); + field.MarkRequired(); + + if (changed && string.IsNullOrEmpty(rowObject.RowAction)) + rowObject.RowAction = RowObject.RowActions.Edit; + + return rowObject; + } + + /// + /// Marks instances in a as required by field numbers. + /// + /// The RowObject to modify. + /// The field numbers to mark as required. + /// The modified RowObject. + public static RowObject? SetRequiredFields(this RowObject rowObject, List? fieldNumbers) + { + var fieldsToSet = ArgumentGuards.ValidateAndNormalizeFieldNumbers(fieldNumbers, nameof(fieldNumbers)); + + if (rowObject == null || rowObject.Fields == null) + return rowObject; + + if (!rowObject.Fields.Any(f => fieldsToSet.Contains(f.FieldNumber))) + throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumbers)); + + var changed = false; + foreach (var field in rowObject.Fields.Where(f => fieldsToSet.Contains(f.FieldNumber))) + { + if (!field.IsRequired()) + { + changed = true; + } + + field.MarkRequired(); + } + + if (changed && string.IsNullOrEmpty(rowObject.RowAction)) + rowObject.RowAction = RowObject.RowActions.Edit; + + return rowObject; + } + + /// + /// Marks a in a as optional by field number. + /// + /// The RowObject to modify. + /// The field number to mark as optional. + /// The modified RowObject. + public static RowObject? SetOptionalField(this RowObject rowObject, string fieldNumber) + { + ArgumentGuards.ValidateFieldNumber(fieldNumber, nameof(fieldNumber)); + + if (rowObject == null || rowObject.Fields == null) + return rowObject; + + var field = rowObject.Fields.FirstOrDefault(f => f.FieldNumber == fieldNumber); + if (field == null) + throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumber)); + + var changed = field.IsRequired(); + field.MarkOptional(); + + if (changed && string.IsNullOrEmpty(rowObject.RowAction)) + rowObject.RowAction = RowObject.RowActions.Edit; + + return rowObject; + } + + /// + /// Marks instances in a as optional by field numbers. + /// + /// The RowObject to modify. + /// The field numbers to mark as optional. + /// The modified RowObject. + public static RowObject? SetOptionalFields(this RowObject rowObject, List? fieldNumbers) + { + var fieldsToSet = ArgumentGuards.ValidateAndNormalizeFieldNumbers(fieldNumbers, nameof(fieldNumbers)); + + if (rowObject == null || rowObject.Fields == null) + return rowObject; + + if (!rowObject.Fields.Any(f => fieldsToSet.Contains(f.FieldNumber))) + throw new ArgumentException(ArgumentGuards.NoMatchingFieldObjectsMessage, nameof(fieldNumbers)); + + var changed = false; + foreach (var field in rowObject.Fields.Where(f => fieldsToSet.Contains(f.FieldNumber))) + { + if (field.IsRequired()) + { + changed = true; + } + + field.MarkOptional(); + } + + if (changed && string.IsNullOrEmpty(rowObject.RowAction)) + rowObject.RowAction = RowObject.RowActions.Edit; + + return rowObject; + } + /// /// Enables all instances in a . ///