RQM fixes for custom Attributes#3997
Conversation
WalkthroughThe pull request introduces significant updates to the Changes
Possibly related PRs
Suggested reviewers
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 4
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (2)
Ginger/GingerCoreNET/DLLS/RQMExportStd.dllis excluded by!**/*.dll,!**/*.dllGinger/GingerCoreNET/DLLS/RQM_RepositoryStd.dllis excluded by!**/*.dll,!**/*.dll
📒 Files selected for processing (2)
Ginger/GingerCoreNET/ALMLib/RQM/ExportToRQM.cs(8 hunks)Ginger/GingerCoreNET/ALMLib/RQM/ImportFromRQM.cs(2 hunks)
🔇 Additional comments (9)
Ginger/GingerCoreNET/ALMLib/RQM/ExportToRQM.cs (6)
111-117: Proper validation of external fields before export
The added check ensures that there are predefined external fields of type "TestCase" before proceeding with the export. This enhances robustness by preventing attempts to export when mandatory fields are missing.
204-204: Passing ExternalFields to GetExeResultforActivityGroup
The ExternalFields parameter is correctly passed to the GetExeResultforActivityGroup method, ensuring that external fields are utilized during execution result retrieval.
252-252: Including ExternalFields in ExportExecutionResult
The ExternalFields parameter is properly included in the call to ExportExecutionResult, which ensures that external fields are considered during the result export process.
384-384: Updating GetExeResultforActivityGroup method signature
The method signature now includes the ExternalFields parameter with a default value of null, enhancing flexibility in handling external fields during execution result processing.
517-517: Passing ExternalFields to CreateExecutionRecord
The ExternalFields parameter is correctly passed to CreateExecutionRecord, ensuring external fields are included when creating execution records.
660-660: Updating CreateExecutionRecord method signature
The method signature now includes the ExternalFields parameter with a default value of null, enabling the inclusion of external fields when creating execution records.
Ginger/GingerCoreNET/ALMLib/RQM/ImportFromRQM.cs (3)
Line range hint 1052-1062: LGTM!
The method GetALMItemFields correctly retrieves item fields based on the online flag.
Line range hint 1063-1073: LGTM!
The method GetALMItemFieldsForDefect properly handles defect item fields retrieval based on the online parameter.
1507-1510: LGTM!
Setting SelectedValue to "Unassigned" when it's null ensures that the field has a default value.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (6)
Ginger/GingerCoreNET/GeneralLib/General.cs (2)
751-751: Add XML documentation for the Type property assignment.The Type property assignment is crucial for the external field mapping functionality. Consider adding a comment to explain its significance.
+ // Preserve the field type from the external item field for proper RQM integration Type = externalItemField.Type,
Line range hint
734-763: Consider enhancing the MapExternalField method.The method could benefit from the following improvements:
- Add XML documentation to describe its purpose and parameters
- Consider making it public to improve reusability
- Add validation for required fields
Here's the suggested implementation:
- private static ExternalItemFieldBase MapExternalField(ExternalItemFieldBase externalItemField) + /// <summary> + /// Maps properties from an external item field to a new instance while preserving existing selected values. + /// </summary> + /// <param name="externalItemField">The source external item field to map from.</param> + /// <returns>A new instance of ExternalItemFieldBase with mapped properties.</returns> + /// <exception cref="ArgumentNullException">Thrown when externalItemField is null.</exception> + public static ExternalItemFieldBase MapExternalField(ExternalItemFieldBase externalItemField) { + if (externalItemField == null) + { + throw new ArgumentNullException(nameof(externalItemField)); + } + + if (string.IsNullOrEmpty(externalItemField.Name)) + { + throw new ArgumentException("Field name is required", nameof(externalItemField)); + } + var existingField = WorkSpace.Instance.Solution.ExternalItemsFields .FirstOrDefault(x => x.Name.Equals(externalItemField.Name, StringComparison.CurrentCultureIgnoreCase)); return new ExternalItemFieldBase { Name = externalItemField.Name, ID = externalItemField.ID, ItemType = externalItemField.ItemType, Type = externalItemField.Type, Guid = externalItemField.Guid, IsCustomField = externalItemField.IsCustomField, SelectedValue = existingField != null && !string.IsNullOrEmpty(existingField.SelectedValue) ? existingField.SelectedValue : externalItemField.SelectedValue }; }Ginger/GingerCoreNET/ALMLib/RQM/ExportToRQM.cs (2)
111-118: Improve error message specificity.The validation for predefined external fields is good, but the error message could be more specific about what TestCase fields are required.
Consider enhancing the error message to list the required TestCase fields:
-Reporter.ToUser(eUserMsgKey.StaticInfoMessage, "Current solution have no predefined values for RQM's mandatory fields. Please configure before doing export. ('ALM'-'ALM Items Fields Configuration')"); +Reporter.ToUser(eUserMsgKey.StaticInfoMessage, "Current solution has no predefined values for RQM's mandatory TestCase fields. Required fields: [list required fields here]. Please configure these fields in 'ALM'-'ALM Items Fields Configuration'.");
1142-1145: Fix indentation for consistency.The indentation of these lines is inconsistent with the surrounding code.
- if (!propertiesList.ContainsKey(itemField.Name)) - { - propertiesList.Add(itemField.Name, itemField.SelectedValue); - } + if (!propertiesList.ContainsKey(itemField.Name)) + { + propertiesList.Add(itemField.Name, itemField.SelectedValue); + }Ginger/GingerCoreNET/ALMLib/RQM/ImportFromRQM.cs (2)
1364-1381: Extract duplicated XML namespace handling logic into a helper method.The XML namespace handling code is duplicated. Consider extracting it into a reusable helper method to improve maintainability and reduce code duplication.
+ private static string GetCustomAttributeMandatory(XmlDocument customAttributeListing) + { + XmlNamespaceManager nsManager = new XmlNamespaceManager(customAttributeListing.NameTable); + nsManager.AddNamespace("ns2", "http://jazz.net/xmlns/alm/qm/v0.1/"); + XmlNode requiredNode = customAttributeListing.SelectSingleNode("//ns2:required", nsManager); + return requiredNode?.InnerText ?? "false"; + }Usage:
- XmlNamespaceManager nsManager = new XmlNamespaceManager(CustomAttributeListing.NameTable); - nsManager.AddNamespace("ns2", "http://jazz.net/xmlns/alm/qm/v0.1/"); - string xpath = "//ns2:required"; - XmlNode requiredNode = CustomAttributeListing.SelectSingleNode(xpath, nsManager); - if (requiredNode != null) - { - CustomAttributeMandatory = CustomAttributeListing.GetElementsByTagName("ns2:required").Item(0).InnerText; - } - else - { - CustomAttributeMandatory = "false"; - } + CustomAttributeMandatory = GetCustomAttributeMandatory(CustomAttributeListing);Also applies to: 1460-1477
1485-1513: Use constants for custom attribute types.String literals for types are used in multiple places. Consider defining constants to improve maintainability and prevent typos.
+ private static class CustomAttributeTypes + { + public const string INTEGER = "INTEGER"; + public const string MEDIUM_STRING = "MEDIUMSTRING"; + public const string SMALL_STRING = "SMALLSTRING"; + public const string TIMESTAMP = "TIMESTAMP"; + } - if(itemfield.Type.Equals("INTEGER",StringComparison.CurrentCultureIgnoreCase)) + if(itemfield.Type.Equals(CustomAttributeTypes.INTEGER, StringComparison.CurrentCultureIgnoreCase))
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (2)
Ginger/GingerCoreNET/DLLS/RQMExportStd.dllis excluded by!**/*.dll,!**/*.dllGinger/GingerCoreNET/DLLS/RQM_RepositoryStd.dllis excluded by!**/*.dll,!**/*.dll
📒 Files selected for processing (3)
Ginger/GingerCoreNET/ALMLib/RQM/ExportToRQM.cs(9 hunks)Ginger/GingerCoreNET/ALMLib/RQM/ImportFromRQM.cs(2 hunks)Ginger/GingerCoreNET/GeneralLib/General.cs(1 hunks)
🔇 Additional comments (4)
Ginger/GingerCoreNET/ALMLib/RQM/ExportToRQM.cs (3)
204-204: LGTM: External fields parameter properly passed.
The ExternalFields parameter is correctly passed to GetExeResultforActivityGroup.
517-517: LGTM: External fields parameter properly passed.
The ExternalFields parameter is correctly passed to CreateExecutionRecord.
928-937: Previous review comment about Contains() is still applicable.
Ginger/GingerCoreNET/ALMLib/RQM/ImportFromRQM.cs (1)
1489-1500:
Fix incorrect DateTime format string.
The format string "yyyy-mm-dd" uses "mm" which represents minutes instead of months. This will produce incorrect dates.
- itemfield.SelectedValue = DateTime.Now.ToString("yyyy-mm-dd");
+ itemfield.SelectedValue = DateTime.Now.ToString("yyyy-MM-dd");Likely invalid or redundant comment.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (3)
Ginger/GingerCoreNET/ALMLib/RQM/ExportToRQM.cs (2)
928-937: Improved duplicate detection in external fields conversion.The updated logic now properly handles field properties and uses ID-based comparison to prevent duplicates. Consider adding null checks for the field properties to improve robustness.
field.ID = fields[indx].ID; -field.Type = fields[indx].Type; -field.TypeIdentifier = fields[indx].TypeIdentifier; -field.IsMultiple = fields[indx].IsMultiple; +field.Type = fields[indx].Type ?? string.Empty; +field.TypeIdentifier = fields[indx].TypeIdentifier ?? string.Empty; +field.IsMultiple = fields[indx].IsMultiple;
Line range hint
789-818: Consider using more specific exception types.The current implementation uses generic Exception catching. Consider catching specific exceptions to handle different error scenarios appropriately.
-try -{ - //Create (RQM)TestCase for each Ginger ActivityGroup and add it to RQM TestCase List - testPlan.Activities = [];//3 - foreach (ActivitiesGroup ag in businessFlow.ActivitiesGroups) - { - if (projEnvironment != null) - { - IValueExpression magVE = new GingerCore.ValueExpression(projEnvironment, businessFlow, [], false, "", false); - ag.CalculateExternalId(magVE); - } - testPlan.Activities.Add(GetTestCaseFromActivityGroup(ag)); - } -} -catch (Exception ex) +try +{ + //Create (RQM)TestCase for each Ginger ActivityGroup and add it to RQM TestCase List + testPlan.Activities = [];//3 + foreach (ActivitiesGroup ag in businessFlow.ActivitiesGroups) + { + if (projEnvironment != null) + { + IValueExpression magVE = new GingerCore.ValueExpression(projEnvironment, businessFlow, [], false, "", false); + ag.CalculateExternalId(magVE); + } + testPlan.Activities.Add(GetTestCaseFromActivityGroup(ag)); + } +} +catch (InvalidOperationException ex) +{ + Reporter.ToLog(eLogLevel.ERROR, $"Failed to calculate external ID: {ex.Message}", ex); + throw; +} +catch (Exception ex)Ginger/GingerCoreNET/ALMLib/RQM/ImportFromRQM.cs (1)
1509-1536: Inconsistent null handling for SelectedValue.The code has redundant null checks and assignments for
SelectedValue. The default value assignment should be consolidated into a single location.Consider refactoring to:
- if (CustomAttributeMandatory.Equals("true",StringComparison.CurrentCultureIgnoreCase)) - { - // ... existing type-specific value assignments ... - } - else - { - itemfield.ToUpdate = false; - itemfield.Mandatory = false; - } - if (itemfield.SelectedValue == null) - { - itemfield.SelectedValue = "Unassigned"; - } + if (CustomAttributeMandatory.Equals("true",StringComparison.CurrentCultureIgnoreCase)) + { + // ... existing type-specific value assignments ... + } + else + { + itemfield.ToUpdate = false; + itemfield.Mandatory = false; + itemfield.SelectedValue = "Unassigned"; + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (2)
Ginger/GingerCoreNET/ALMLib/RQM/ExportToRQM.cs(9 hunks)Ginger/GingerCoreNET/ALMLib/RQM/ImportFromRQM.cs(2 hunks)
🔇 Additional comments (5)
Ginger/GingerCoreNET/ALMLib/RQM/ExportToRQM.cs (3)
111-118: Good addition of validation for required RQM fields!
The check for TestCase type fields ensures that mandatory RQM fields are configured before proceeding with the export, preventing potential issues downstream.
204-204: Well-structured propagation of external fields through execution chain.
The addition of the ExternalFields parameter with a default null value maintains backward compatibility while enabling the new functionality.
Also applies to: 252-252
1142-1145: Good defensive programming with dictionary key check.
The ContainsKey check prevents potential duplicate key exceptions when adding properties.
Ginger/GingerCoreNET/ALMLib/RQM/ImportFromRQM.cs (2)
1364-1381: Improved XML namespace handling and error resilience.
The code adds proper XML namespace handling for retrieving the 'required' attribute, with a fallback to "false" when not found. This is a good practice for handling optional XML elements.
1389-1407: Good default value handling for mandatory custom attributes.
The code properly sets default values based on field types for mandatory custom attributes:
- INTEGER → "1"
- MEDIUMSTRING/SMALLSTRING → "dummy"
- TIMESTAMP → Current date in "yyyy-MM-dd" format
This ensures data consistency when importing.
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Outside diff range and nitpick comments (1)
Ginger/GingerCoreNET/GeneralLib/General.cs (1)
754-781: Simplify the nested conditional logic.The current implementation has deeply nested if conditions that make the code hard to follow. Consider simplifying the logic by combining conditions and extracting the value determination logic into a separate method.
-if (existingField == null) -{ - if (externalItemField.Mandatory) - { - if (!string.IsNullOrEmpty(externalItemField.SelectedValue)) - { - value = externalItemField.SelectedValue; - } - else - { - value = GetDefaultValue(externalItemField); - } - } -} -else -{ - if (externalItemField.Mandatory) - { - if (!string.IsNullOrEmpty(existingField.SelectedValue)) - { - value = existingField.SelectedValue; - } - else - { - value = GetDefaultValue(externalItemField); - } - } -} +string value = string.Empty; +if (externalItemField.Mandatory) +{ + value = existingField?.SelectedValue ?? externalItemField.SelectedValue; + if (string.IsNullOrEmpty(value)) + { + value = GetDefaultValue(externalItemField); + } +}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (1)
Ginger/GingerCoreNET/DLLS/RQMExportStd.dllis excluded by!**/*.dll,!**/*.dll
📒 Files selected for processing (1)
Ginger/GingerCoreNET/GeneralLib/General.cs(2 hunks)
🔇 Additional comments (1)
Ginger/GingerCoreNET/GeneralLib/General.cs (1)
730-734: LGTM! Null check improves robustness.
The addition of the null check before adding mapped items prevents potential null reference exceptions and improves the method's reliability.
Thank you for your contribution.
Before submitting this PR, please make sure:
Summary by CodeRabbit
New Features
Bug Fixes
Documentation