From 43a348669a3e221417d5bf99099dd02b81ff2691 Mon Sep 17 00:00:00 2001 From: Dmitry Ermakovich Date: Fri, 10 Jan 2025 09:48:50 +0300 Subject: [PATCH] fix: TMS-30455: add features and stories sections for allure https://work.teamstorm.io/tasks/item/TMS-30455 --- .../AllureExporter/AllureExporter.csproj | 3 + Migrators/AllureExporter/Client/Client.cs | 30 +++---- .../AllureExporter/Models/AllureAttachment.cs | 6 +- .../Models/AllureCustomField.cs | 6 +- Migrators/AllureExporter/Models/AllureLink.cs | 4 +- .../AllureExporter/Models/AllureSharedStep.cs | 16 ++-- Migrators/AllureExporter/Models/AllureStep.cs | 16 ++-- .../AllureExporter/Models/AllureTestCase.cs | 16 ++-- Migrators/AllureExporter/Models/BaseEntity.cs | 4 +- Migrators/AllureExporter/Models/Constants.cs | 2 + .../AllureExporter/Services/ExportService.cs | 2 +- .../Services/ITestCaseService.cs | 3 +- .../AllureExporter/Services/StepService.cs | 10 +-- .../Services/TestCaseService.cs | 51 +++++++++++- Migrators/Importer/Client/Client.cs | 15 +++- Migrators/Importer/Importer.csproj | 3 + Migrators/Importer/Models/TmsAttribute.cs | 6 +- .../Importer/Models/TmsAttributeOptions.cs | 2 +- Migrators/Importer/Models/TmsIterations.cs | 2 +- Migrators/Importer/Models/TmsParameter.cs | 4 +- Migrators/Importer/Models/TmsTestCase.cs | 2 +- .../Importer/Services/AttributeService.cs | 2 - .../Importer/Services/BaseWorkItemService.cs | 12 +-- .../Importer/Services/SharedStepService.cs | 4 +- .../Importer/Services/TestCaseService.cs | 6 +- Migrators/Models/Section.cs | 80 +++++++++++++++++++ 26 files changed, 225 insertions(+), 82 deletions(-) diff --git a/Migrators/AllureExporter/AllureExporter.csproj b/Migrators/AllureExporter/AllureExporter.csproj index 6d38471..dea1578 100644 --- a/Migrators/AllureExporter/AllureExporter.csproj +++ b/Migrators/AllureExporter/AllureExporter.csproj @@ -9,6 +9,9 @@ true win-x64;linux-x64;osx-x64 + + false + diff --git a/Migrators/AllureExporter/Client/Client.cs b/Migrators/AllureExporter/Client/Client.cs index 161a9a7..aaf8acf 100644 --- a/Migrators/AllureExporter/Client/Client.cs +++ b/Migrators/AllureExporter/Client/Client.cs @@ -102,7 +102,7 @@ public async Task> GetTestCaseIdsFromMainSuite(int projectId) } var content = await response.Content.ReadAsStringAsync(); - var testCases = JsonSerializer.Deserialize(content); + var testCases = JsonSerializer.Deserialize(content)!; totalPages = testCases.TotalPages; testCaseIds.AddRange(testCases.Content @@ -141,7 +141,7 @@ public async Task> GetTestCaseIdsFromSuite(int projectId, int suiteId) } var content = await response.Content.ReadAsStringAsync(); - var testCases = JsonSerializer.Deserialize(content); + var testCases = JsonSerializer.Deserialize(content)!; totalPages = testCases.TotalPages; testCaseIds.AddRange(testCases.Content @@ -180,7 +180,7 @@ public async Task> GetSharedStepsByProjectId(int projectI } var content = await response.Content.ReadAsStringAsync(); - var sharedSteps = JsonSerializer.Deserialize(content); + var sharedSteps = JsonSerializer.Deserialize(content)!; totalPages = sharedSteps.TotalPages; allSharedSteps.AddRange(sharedSteps.Content); @@ -211,7 +211,7 @@ public async Task GetTestCaseById(int testCaseId) } var content = await response.Content.ReadAsStringAsync(); - return JsonSerializer.Deserialize(content); + return JsonSerializer.Deserialize(content)!; } public async Task> GetSteps(int testCaseId) @@ -230,7 +230,7 @@ public async Task> GetSteps(int testCaseId) } var content = await response.Content.ReadAsStringAsync(); - var steps = JsonSerializer.Deserialize(content); + var steps = JsonSerializer.Deserialize(content)!; return steps.Steps; } @@ -251,7 +251,7 @@ public async Task GetStepsInfoByTestCaseId(int testCaseId) } var content = await response.Content.ReadAsStringAsync(); - var stepsInfo = JsonSerializer.Deserialize(content); + var stepsInfo = JsonSerializer.Deserialize(content)!; return stepsInfo; } @@ -272,7 +272,7 @@ public async Task GetStepsInfoBySharedStepId(int sharedSt } var content = await response.Content.ReadAsStringAsync(); - var sharedStepsInfo = JsonSerializer.Deserialize(content); + var sharedStepsInfo = JsonSerializer.Deserialize(content)!; return sharedStepsInfo; } @@ -299,7 +299,7 @@ public async Task> GetAttachmentsByTestCaseId(int testCas } var content = await response.Content.ReadAsStringAsync(); - var attachments = JsonSerializer.Deserialize(content); + var attachments = JsonSerializer.Deserialize(content)!; totalPages = attachments.TotalPages; allAttachments.AddRange(attachments.Content); @@ -334,7 +334,7 @@ public async Task> GetAttachmentsBySharedStepId(int share } var content = await response.Content.ReadAsStringAsync(); - var attachments = JsonSerializer.Deserialize(content); + var attachments = JsonSerializer.Deserialize(content)!; totalPages = attachments.TotalPages; allAttachments.AddRange(attachments.Content); @@ -363,7 +363,7 @@ public async Task> GetLinks(int testCaseId) } var content = await response.Content.ReadAsStringAsync(); - return JsonSerializer.Deserialize>(content); + return JsonSerializer.Deserialize>(content)!; } public async Task> GetSuites(int projectId) @@ -382,7 +382,7 @@ public async Task> GetSuites(int projectId) } var content = await response.Content.ReadAsStringAsync(); - var suites = JsonSerializer.Deserialize(content); + var suites = JsonSerializer.Deserialize(content)!; return suites.Content.ToList(); } @@ -436,7 +436,7 @@ public async Task> GetTestLayers() } var content = await response.Content.ReadAsStringAsync(); - var layers = JsonSerializer.Deserialize(content); + var layers = JsonSerializer.Deserialize(content)!; return layers.Content.ToList(); } @@ -457,7 +457,7 @@ public async Task> GetCustomFieldNames(int projectId) } var content = await response.Content.ReadAsStringAsync(); - var customFields = JsonSerializer.Deserialize>(content); + var customFields = JsonSerializer.Deserialize>(content)!; return customFields; } @@ -478,7 +478,7 @@ public async Task> GetCustomFieldValues(int fieldId) } var content = await response.Content.ReadAsStringAsync(); - var values = JsonSerializer.Deserialize(content); + var values = JsonSerializer.Deserialize(content)!; return values.Content.ToList(); } @@ -499,7 +499,7 @@ public async Task> GetCustomFieldsFromTestCase(int testC } var content = await response.Content.ReadAsStringAsync(); - var customFields = JsonSerializer.Deserialize>(content); + var customFields = JsonSerializer.Deserialize>(content)!; return customFields; } diff --git a/Migrators/AllureExporter/Models/AllureAttachment.cs b/Migrators/AllureExporter/Models/AllureAttachment.cs index 7de83d3..ac5d6f2 100644 --- a/Migrators/AllureExporter/Models/AllureAttachment.cs +++ b/Migrators/AllureExporter/Models/AllureAttachment.cs @@ -7,17 +7,17 @@ public class AllureAttachment [JsonPropertyName("id")] public int Id { get; set; } [JsonPropertyName("name")] - public string Name { get; set; } + public string Name { get; set; } = string.Empty; [JsonPropertyName("contentType")] - public string ContentType { get; set; } + public string ContentType { get; set; } = string.Empty; } public class AllureAttachmentContent { [JsonPropertyName("content")] - public List Content { get; set; } + public List Content { get; set; } = new (); [JsonPropertyName("totalPages")] public int TotalPages { get; set; } diff --git a/Migrators/AllureExporter/Models/AllureCustomField.cs b/Migrators/AllureExporter/Models/AllureCustomField.cs index c66b290..612f3dd 100644 --- a/Migrators/AllureExporter/Models/AllureCustomField.cs +++ b/Migrators/AllureExporter/Models/AllureCustomField.cs @@ -5,15 +5,15 @@ namespace AllureExporter.Models; public class AllureCustomField { [JsonPropertyName("name")] - public string Name { get; set; } + public string Name { get; set; } = string.Empty; [JsonPropertyName("customField")] - public CustomField CustomField { get; set; } + public CustomField? CustomField { get; set; } } public class CustomField { [JsonPropertyName("name")] - public string Name { get; set; } + public string Name { get; set; } = string.Empty; } diff --git a/Migrators/AllureExporter/Models/AllureLink.cs b/Migrators/AllureExporter/Models/AllureLink.cs index 4962864..06ca20e 100644 --- a/Migrators/AllureExporter/Models/AllureLink.cs +++ b/Migrators/AllureExporter/Models/AllureLink.cs @@ -5,9 +5,9 @@ namespace AllureExporter.Models; public class AllureLink { [JsonPropertyName("name")] - public string Name { get; set; } + public string Name { get; set; } = string.Empty; [JsonPropertyName("url")] - public string Url { get; set; } + public string Url { get; set; } = string.Empty; } diff --git a/Migrators/AllureExporter/Models/AllureSharedStep.cs b/Migrators/AllureExporter/Models/AllureSharedStep.cs index 30815f5..6378947 100644 --- a/Migrators/AllureExporter/Models/AllureSharedStep.cs +++ b/Migrators/AllureExporter/Models/AllureSharedStep.cs @@ -6,7 +6,7 @@ namespace AllureExporter.Models; public class AllureSharedSteps { [JsonPropertyName("content")] - public List Content { get; set; } + public List Content { get; set; } = new(); [JsonPropertyName("totalPages")] public int TotalPages { get; set; } @@ -21,32 +21,32 @@ public class AllureSharedStepBase public class AllureSharedStep : AllureSharedStepBase { [JsonPropertyName("name")] - public string Name { get; set; } + public string Name { get; set; } = string.Empty; } public class AllureSharedStepInfo : AllureSharedStepBase { [JsonPropertyName("body")] - public string Name { get; set; } + public string Name { get; set; } = string.Empty; [JsonPropertyName("children")] - public List NestedStepIds { get; set; } + public List NestedStepIds { get; set; } = new(); } public class AllureScenarioRoot { [JsonPropertyName("children")] - public List NestedStepIds { get; set; } + public List NestedStepIds { get; set; } = new(); } public class AllureSharedStepsInfo { [JsonPropertyName("root")] - public AllureScenarioRoot Root { get; set; } + public AllureScenarioRoot? Root { get; set; } [JsonPropertyName("sharedStepScenarioSteps")] - public Dictionary SharedStepScenarioStepsDictionary { get; set; } + public Dictionary SharedStepScenarioStepsDictionary { get; set; } = new(); [JsonPropertyName("sharedStepAttachments")] - public Dictionary SharedStepAttachmentsDictionary { get; set; } + public Dictionary SharedStepAttachmentsDictionary { get; set; } = new(); } diff --git a/Migrators/AllureExporter/Models/AllureStep.cs b/Migrators/AllureExporter/Models/AllureStep.cs index fb9adc2..6b10d02 100644 --- a/Migrators/AllureExporter/Models/AllureStep.cs +++ b/Migrators/AllureExporter/Models/AllureStep.cs @@ -5,25 +5,25 @@ namespace AllureExporter.Models; public class AllureStep { [JsonPropertyName("name")] - public string Name { get; set; } + public string Name { get; set; } = string.Empty; [JsonPropertyName("attachments")] public List? Attachments { get; set; } [JsonPropertyName("steps")] - public List Steps { get; set; } + public List Steps { get; set; } = new(); [JsonPropertyName("keyword")] - public string Keyword { get; set; } + public string Keyword { get; set; } = string.Empty; [JsonPropertyName("expectedResult")] - public string ExpectedResult { get; set; } + public string ExpectedResult { get; set; } = string.Empty; } public class AllureSteps { [JsonPropertyName("steps")] - public List Steps { get; set; } + public List Steps { get; set; } = new(); } public class AllureScenarioStep @@ -50,11 +50,11 @@ public class AllureScenarioStep public class AllureStepsInfo : AllureSharedStepsInfo { [JsonPropertyName("scenarioSteps")] - public Dictionary ScenarioStepsDictionary { get; set; } + public Dictionary ScenarioStepsDictionary { get; set; } = new(); [JsonPropertyName("attachments")] - public Dictionary AttachmentsDictionary { get; set; } + public Dictionary AttachmentsDictionary { get; set; } = new(); [JsonPropertyName("sharedSteps")] - public Dictionary SharedStepsDictionary { get; set; } + public Dictionary SharedStepsDictionary { get; set; } = new(); } diff --git a/Migrators/AllureExporter/Models/AllureTestCase.cs b/Migrators/AllureExporter/Models/AllureTestCase.cs index 3edd709..b84f2a4 100644 --- a/Migrators/AllureExporter/Models/AllureTestCase.cs +++ b/Migrators/AllureExporter/Models/AllureTestCase.cs @@ -6,7 +6,7 @@ namespace AllureExporter.Models; public class AllureTestCases { [JsonPropertyName("content")] - public List Content { get; set; } + public List Content { get; set; } = new(); [JsonPropertyName("totalPages")] public int TotalPages { get; set; } @@ -24,16 +24,16 @@ public class AllureTestCaseBase public class AllureTestCase : AllureTestCaseBase { [JsonPropertyName("name")] - public string Name { get; set; } + public string Name { get; set; } = string.Empty; [JsonPropertyName("description")] - public string Description { get; set; } + public string Description { get; set; } = string.Empty; [JsonPropertyName("tags")] - public List Tags { get; set; } + public List Tags { get; set; } = new(); [JsonPropertyName("status")] - public Status Status { get; set; } + public Status? Status { get; set; } [JsonPropertyName("testLayer")] public TestLayer? Layer { get; set; } @@ -45,17 +45,17 @@ public class AllureTestCase : AllureTestCaseBase public class Tags { [JsonPropertyName("name")] - public string Name { get; set; } + public string Name { get; set; } = string.Empty; } public class Status { [JsonPropertyName("name")] - public string Name { get; set; } + public string Name { get; set; } = string.Empty; } public class TestLayer { [JsonPropertyName("name")] - public string Name { get; set; } + public string Name { get; set; } = string.Empty; } diff --git a/Migrators/AllureExporter/Models/BaseEntity.cs b/Migrators/AllureExporter/Models/BaseEntity.cs index 4540a57..594fd07 100644 --- a/Migrators/AllureExporter/Models/BaseEntity.cs +++ b/Migrators/AllureExporter/Models/BaseEntity.cs @@ -8,13 +8,13 @@ public class BaseEntity public int Id { get; set; } [JsonPropertyName("name")] - public string Name { get; set; } + public string Name { get; set; } = string.Empty; } public class BaseEntities { [JsonPropertyName("content")] - public List Content { get; set; } + public List Content { get; set; } = new(); } diff --git a/Migrators/AllureExporter/Models/Constants.cs b/Migrators/AllureExporter/Models/Constants.cs index 8b859fd..ce6d3d3 100644 --- a/Migrators/AllureExporter/Models/Constants.cs +++ b/Migrators/AllureExporter/Models/Constants.cs @@ -5,4 +5,6 @@ public class Constants public const int MainSectionId = 0; public const string AllureStatus = "AllureStatus"; public const string AllureTestLayer = "Test Layer"; + public const string Feature = "Feature"; + public const string Story = "Story"; } diff --git a/Migrators/AllureExporter/Services/ExportService.cs b/Migrators/AllureExporter/Services/ExportService.cs index 36d18ff..2ab1dad 100644 --- a/Migrators/AllureExporter/Services/ExportService.cs +++ b/Migrators/AllureExporter/Services/ExportService.cs @@ -39,7 +39,7 @@ public virtual async Task ExportProject() var sharedSteps = await _sharedStepService.ConvertSharedSteps(project.Id, section.MainSection.Id, attributes); var sharedStepsMap = sharedSteps.ToDictionary(k => k.Key.ToString(), v => v.Value.Id); var testCases = - await _testCaseService.ConvertTestCases(project.Id, sharedStepsMap, customAttributes, section.SectionDictionary); + await _testCaseService.ConvertTestCases(project.Id, sharedStepsMap, customAttributes, section); foreach (var sharedStep in sharedSteps) { diff --git a/Migrators/AllureExporter/Services/ITestCaseService.cs b/Migrators/AllureExporter/Services/ITestCaseService.cs index 6e721f0..939cd97 100644 --- a/Migrators/AllureExporter/Services/ITestCaseService.cs +++ b/Migrators/AllureExporter/Services/ITestCaseService.cs @@ -1,8 +1,9 @@ +using AllureExporter.Models; using Models; namespace AllureExporter.Services; public interface ITestCaseService { - Task> ConvertTestCases(int projectId, Dictionary sharedStepMap, Dictionary attributes, Dictionary sectionIdMap); + Task> ConvertTestCases(int projectId, Dictionary sharedStepMap, Dictionary attributes, SectionInfo sectionInfo); } diff --git a/Migrators/AllureExporter/Services/StepService.cs b/Migrators/AllureExporter/Services/StepService.cs index ca33ec9..6afcd66 100644 --- a/Migrators/AllureExporter/Services/StepService.cs +++ b/Migrators/AllureExporter/Services/StepService.cs @@ -58,7 +58,7 @@ public async Task> ConvertStepsForTestCase(int testCaseId, Dictionary _logger.LogDebug("Found stepsInfo by test case id {TestCaseId}: {@StepsInfo}", testCaseId, stepsInfo); - return ConvertStepsFromStepsInfo(stepsInfo.Root.NestedStepIds, stepsInfo, commonAttachments, sharedStepMap); + return ConvertStepsFromStepsInfo(stepsInfo.Root!.NestedStepIds, stepsInfo, commonAttachments, sharedStepMap); } private static List ConvertStepsFromStepsInfo( @@ -84,14 +84,14 @@ private static List ConvertStepsFromStepsInfo( if (allureStep.SharedStepId != null) { - step.SharedStepId = sharedStepMap[allureStep.SharedStepId.ToString()]; + step.SharedStepId = sharedStepMap[allureStep.SharedStepId.ToString()!]; } if (allureStep.AttachmentId != null) { step.ActionAttachments.AddRange( GetAttachments( - [stepsInfo.AttachmentsDictionary[allureStep.AttachmentId.ToString()]], + [stepsInfo.AttachmentsDictionary[allureStep.AttachmentId.ToString()!]], commonAttachments)); } @@ -115,7 +115,7 @@ public async Task> ConvertStepsForSharedStep(int sharedStepId) _logger.LogDebug("Found stepsInfo by shared step id {SharedStepId}: {@StepsInfo}", sharedStepId, stepsInfo); - return ConvertStepsFromSharedStepsInfo(stepsInfo.Root.NestedStepIds, stepsInfo, commonAttachments); + return ConvertStepsFromSharedStepsInfo(stepsInfo.Root!.NestedStepIds, stepsInfo, commonAttachments); } private static List ConvertStepsFromSharedStepsInfo( @@ -147,7 +147,7 @@ private static List ConvertStepsFromSharedStepsInfo( { step.ActionAttachments.AddRange( GetAttachments( - [stepsInfo.SharedStepAttachmentsDictionary[allureStep.AttachmentId.ToString()]], + [stepsInfo.SharedStepAttachmentsDictionary[allureStep.AttachmentId.ToString()!]], commonAttachments)); } diff --git a/Migrators/AllureExporter/Services/TestCaseService.cs b/Migrators/AllureExporter/Services/TestCaseService.cs index b74da48..5e6fdae 100644 --- a/Migrators/AllureExporter/Services/TestCaseService.cs +++ b/Migrators/AllureExporter/Services/TestCaseService.cs @@ -26,8 +26,9 @@ public async Task> ConvertTestCases( int projectId, Dictionary sharedStepMap, Dictionary attributes, - Dictionary sectionIdMap) + SectionInfo sectionInfo) { + var sectionIdMap = sectionInfo.SectionDictionary; _logger.LogInformation("Converting test cases"); var testCases = new List(); @@ -46,7 +47,7 @@ public async Task> ConvertTestCases( foreach (var testCaseId in ids) { var testCase = await ConvertTestCase(testCaseId, sharedStepMap, section.Value, attributes); - + ProcessFeatureSection(testCase, attributes, sectionInfo); testCases.Add(testCase); } } @@ -56,6 +57,47 @@ public async Task> ConvertTestCases( return testCases; } + private string GetAttributeNameById(Guid id, List caseAttributes) + { + var attr = caseAttributes.FirstOrDefault(x => + x.Id == id); + return attr?.Value.ToString() ?? string.Empty; + } + + /// + /// create feauture and story sections, attach testCase to the story; + /// + /// true if processed successfully + protected virtual bool ProcessFeatureSection(TestCase testCase, + Dictionary attributes, + SectionInfo sectionInfo) + { + string featureString = GetAttributeNameById(attributes[Constants.Feature], testCase.Attributes); + string storyString = GetAttributeNameById(attributes[Constants.Story], testCase.Attributes); + if (featureString == "" || storyString == "") return false; + + Section currentSection = Section.FindSection(s => s.Id == testCase.SectionId, sectionInfo.MainSection)!; + + var featureSection = Section.FindSection( + s => s.Name == featureString, currentSection); + if (featureSection == null) + { + featureSection = Section.CreateSection(featureString); + currentSection.Sections.Add(featureSection); + } + var storySection = Section.FindSection( + s => s.Name == storyString, featureSection); + if (storySection == null) + { + storySection = Section.CreateSection(storyString); + featureSection.Sections.Add(storySection); + } + testCase.SectionId = storySection.Id; + + return true; + } + + protected virtual async Task ConvertTestCase( int testCaseId, Dictionary sharedStepMap, @@ -111,7 +153,7 @@ private async Task> ConvertAttributes(int testCaseId, Allure new CaseAttribute { Id = attributes[Constants.AllureStatus], - Value = testCase.Status.Name + Value = testCase.Status!.Name }, new CaseAttribute { @@ -129,7 +171,8 @@ private async Task> ConvertAttributes(int testCaseId, Allure continue; } - var customField = customFields.FirstOrDefault(cf => cf.CustomField.Name == attribute.Key); + var customField = customFields.FirstOrDefault( + cf => cf.CustomField!.Name == attribute.Key); if (customField != null) { diff --git a/Migrators/Importer/Client/Client.cs b/Migrators/Importer/Client/Client.cs index 8eb95c9..94f0574 100644 --- a/Migrators/Importer/Client/Client.cs +++ b/Migrators/Importer/Client/Client.cs @@ -1,6 +1,7 @@ using Importer.Models; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Models; using TestIT.ApiClient.Api; using TestIT.ApiClient.Client; @@ -23,7 +24,7 @@ public class Client : IClient private readonly CustomAttributesApi _customAttributesApi; private readonly ParametersApi _parametersApi; private readonly bool _importToExistingProject; - private readonly string _projectName; + private readonly string? _projectName; private const int TenMinutes = 60000; @@ -90,7 +91,10 @@ public async Task GetProject(string name) try { - var projects = await _projectsApi.ApiV2ProjectsSearchPostAsync(null, null, null, null, null, new ApiV2ProjectsSearchPostRequest(name: name)); + var projects = await + _projectsApi.ApiV2ProjectsSearchPostAsync( + null, null, null!, null!, null!, + new ApiV2ProjectsSearchPostRequest(name: name)); _logger.LogDebug("Got projects {@Project} by name {Name}", projects, name); @@ -231,6 +235,13 @@ public async Task ImportAttribute(Attribute attribute) IsEnabled = attribute.IsActive, Options = attribute.Options.Select(o => new CustomAttributeOptionPostModel(value: o)).ToList() }; + if (model.Options.Count == 0 && ( + model.Type == CustomAttributeTypesEnum.Options + || model.Type == CustomAttributeTypesEnum.MultipleOptions + )) + { + model.Options.Add(new CustomAttributeOptionPostModel("null")); + } _logger.LogDebug("Importing attribute {@Attribute}", model); diff --git a/Migrators/Importer/Importer.csproj b/Migrators/Importer/Importer.csproj index 3441c06..eecbaca 100644 --- a/Migrators/Importer/Importer.csproj +++ b/Migrators/Importer/Importer.csproj @@ -9,6 +9,9 @@ true win-x64;linux-x64;osx-x64 + + false + diff --git a/Migrators/Importer/Models/TmsAttribute.cs b/Migrators/Importer/Models/TmsAttribute.cs index 0ee6c28..7b33302 100644 --- a/Migrators/Importer/Models/TmsAttribute.cs +++ b/Migrators/Importer/Models/TmsAttribute.cs @@ -3,10 +3,10 @@ namespace Importer.Models; public class TmsAttribute { public Guid Id { get; set; } - public string Name { get; set; } + public string Name { get; set; } = string.Empty; public bool IsEnabled { get; set; } public bool IsRequired { get; set; } - public string Type { get; set; } + public string Type { get; set; } = string.Empty; public bool IsGlobal { get; set; } - public List Options { get; set; } + public List Options { get; set; } = new(); } diff --git a/Migrators/Importer/Models/TmsAttributeOptions.cs b/Migrators/Importer/Models/TmsAttributeOptions.cs index eafc447..8cfe479 100644 --- a/Migrators/Importer/Models/TmsAttributeOptions.cs +++ b/Migrators/Importer/Models/TmsAttributeOptions.cs @@ -3,6 +3,6 @@ namespace Importer.Models; public class TmsAttributeOptions { public Guid Id { get; set; } - public string Value { get; set; } + public string Value { get; set; } = string.Empty; public bool IsDefault { get; set; } } diff --git a/Migrators/Importer/Models/TmsIterations.cs b/Migrators/Importer/Models/TmsIterations.cs index ee6a90e..ddcfc2b 100644 --- a/Migrators/Importer/Models/TmsIterations.cs +++ b/Migrators/Importer/Models/TmsIterations.cs @@ -2,5 +2,5 @@ namespace Importer.Models; public class TmsIterations { - public List Parameters { get; set; } + public List Parameters { get; set; } = new(); } diff --git a/Migrators/Importer/Models/TmsParameter.cs b/Migrators/Importer/Models/TmsParameter.cs index a116ab9..2fb695a 100644 --- a/Migrators/Importer/Models/TmsParameter.cs +++ b/Migrators/Importer/Models/TmsParameter.cs @@ -3,7 +3,7 @@ namespace Importer.Models; public class TmsParameter { public Guid Id { get; set; } - public string Value { get; set; } - public string Name { get; set; } + public string Value { get; set; } = string.Empty; + public string Name { get; set; } = string.Empty; public Guid ParameterKeyId { get; set; } } diff --git a/Migrators/Importer/Models/TmsTestCase.cs b/Migrators/Importer/Models/TmsTestCase.cs index c076684..557fc97 100644 --- a/Migrators/Importer/Models/TmsTestCase.cs +++ b/Migrators/Importer/Models/TmsTestCase.cs @@ -5,7 +5,7 @@ namespace Importer.Models; public class TmsTestCase : TestCase { - public List TmsIterations { get; set; } + public List TmsIterations { get; set; } = new(); public static TmsTestCase Convert(TestCase testCase) { diff --git a/Migrators/Importer/Services/AttributeService.cs b/Migrators/Importer/Services/AttributeService.cs index b3a058c..2e968bb 100644 --- a/Migrators/Importer/Services/AttributeService.cs +++ b/Migrators/Importer/Services/AttributeService.cs @@ -46,9 +46,7 @@ public async Task> ImportAttributes(Guid projectI var attributeId = await _client.ImportAttribute(attribute); attributeId = await _client.GetAttribute(attributeId.Id); - attributesMap.Add(attribute.Id, attributeId); - attributeIsNotImported = false; } else diff --git a/Migrators/Importer/Services/BaseWorkItemService.cs b/Migrators/Importer/Services/BaseWorkItemService.cs index a96f1e3..3076af9 100644 --- a/Migrators/Importer/Services/BaseWorkItemService.cs +++ b/Migrators/Importer/Services/BaseWorkItemService.cs @@ -32,23 +32,25 @@ private static object ConvertAttributeValue(TmsAttribute tmsAttribute, CaseAttri { if (string.Equals(tmsAttribute.Type, OptionsType, StringComparison.InvariantCultureIgnoreCase)) { - return Enumerable.FirstOrDefault(tmsAttribute.Options, o => o.Value == caseAttribute.Value.ToString())?.Id.ToString(); + return Enumerable.FirstOrDefault(tmsAttribute.Options, + o => o.Value == caseAttribute.Value.ToString())?.Id.ToString()!; } else if (string.Equals(tmsAttribute.Type, MultipleOptionsType, StringComparison.InvariantCultureIgnoreCase)) { var ids = new List(); - var options = JsonSerializer.Deserialize>(caseAttribute.Value.ToString()); + var options = JsonSerializer.Deserialize>(caseAttribute.Value.ToString()!)!; foreach (var option in options) { - ids.Add(Enumerable.FirstOrDefault(tmsAttribute.Options, o => o.Value == option)?.Id.ToString()); + ids.Add(Enumerable.FirstOrDefault(tmsAttribute.Options, + o => o.Value == option)?.Id.ToString()!); } return ids; } else if (string.Equals(tmsAttribute.Type, Checkbox, StringComparison.InvariantCultureIgnoreCase)) { - return bool.Parse(caseAttribute.Value.ToString()); + return bool.Parse(caseAttribute.Value.ToString()!); } if (Guid.TryParse(caseAttribute.Value.ToString(), out _)) @@ -56,7 +58,7 @@ private static object ConvertAttributeValue(TmsAttribute tmsAttribute, CaseAttri return "uuid " + caseAttribute.Value.ToString(); } - return caseAttribute.Value.ToString(); + return caseAttribute.Value.ToString()!; } /// diff --git a/Migrators/Importer/Services/SharedStepService.cs b/Migrators/Importer/Services/SharedStepService.cs index 0deaa8b..5c9ef52 100644 --- a/Migrators/Importer/Services/SharedStepService.cs +++ b/Migrators/Importer/Services/SharedStepService.cs @@ -11,8 +11,8 @@ public class SharedStepService : BaseWorkItemService, ISharedStepService private readonly IClient _client; private readonly IParserService _parserService; private readonly IAttachmentService _attachmentService; - private Dictionary _attributesMap; - private Dictionary _sectionsMap; + private Dictionary _attributesMap = new(); + private Dictionary _sectionsMap = new(); private readonly Dictionary _sharedSteps = new(); public SharedStepService(ILogger logger, IClient client, IParserService parserService, diff --git a/Migrators/Importer/Services/TestCaseService.cs b/Migrators/Importer/Services/TestCaseService.cs index a19cc30..d787d54 100644 --- a/Migrators/Importer/Services/TestCaseService.cs +++ b/Migrators/Importer/Services/TestCaseService.cs @@ -14,9 +14,9 @@ class TestCaseService : BaseWorkItemService, ITestCaseService private readonly IClient _client; private readonly IParserService _parserService; - private Dictionary _attributesMap; - private Dictionary _sectionsMap; - private Dictionary _sharedSteps; + private Dictionary _attributesMap = new(); + private Dictionary _sectionsMap = new(); + private Dictionary _sharedSteps = new(); public TestCaseService(ILogger logger, IClient client, IParserService parserService, IParameterService parameterService, IAttachmentService attachmentService) diff --git a/Migrators/Models/Section.cs b/Migrators/Models/Section.cs index 6a7b6ad..af8e9eb 100644 --- a/Migrators/Models/Section.cs +++ b/Migrators/Models/Section.cs @@ -20,4 +20,84 @@ public class Section [JsonPropertyName("sections")] public List
Sections { get; set; } + + public static Section CreateSection(string name) => new() + { + Id = Guid.NewGuid(), + Name = name, + PreconditionSteps = new List(), + PostconditionSteps = new List(), + Sections = new List
() + }; + + // public static Section? FindSectionById(Guid id, Section sectionRoot) + // { + // if (sectionRoot.Id == id) return sectionRoot; + // foreach (var section in sectionRoot.Sections) + // { + // var res = FindSectionById(id, section); + // if (res != null) return res; + // } + // return null; + // } + // + // public static Section? FindSectionByName(string name, Section sectionRoot) + // { + // if (sectionRoot.Name == name) return sectionRoot; + // foreach (var section in sectionRoot.Sections) + // { + // var res = FindSectionByName(name, section); + // if (res != null) return res; + // } + // return null; + // } + + /// + /// BFS + /// + public static Section? FindSection(Func predicate, Section sectionRoot) + { + var queue = new Queue
(); + queue.Enqueue(sectionRoot); + + while (queue.Count > 0) + { + var current = queue.Dequeue(); + if (predicate(current)) + return current; + + foreach (var section in current.Sections) + { + queue.Enqueue(section); + } + } + + return null; + } + + /// + /// parallel handling + /// + public static Section? FindSectionParallel(Func predicate, Section sectionRoot) + { + Section? result = null; + var sectionsToCheck = new List
{ sectionRoot }; + + Parallel.ForEach(sectionsToCheck, (section, state) => + { + if (result != null) state.Stop(); + if (predicate(section)) + { + result = section; + state.Stop(); + } + + lock (sectionsToCheck) + { + sectionsToCheck.AddRange(section.Sections); + } + }); + + return result; + } }