From 0094f595fd773708f3c4823c1031c2351f3fcebe Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Wed, 6 Nov 2024 16:25:27 +0300 Subject: [PATCH 1/4] Fix `@Issue` and `@Issues` annotations handling in certain cases --- CHANGELOG.md | 2 ++ .../epam/reportportal/service/LaunchImpl.java | 22 +++++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a449bef1..34c2055d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog ## [Unreleased] +### Fixed +- `@Issue` and `@Issues` annotations handling in certain cases, by @HardNorth ## [5.2.19] ### Added diff --git a/src/main/java/com/epam/reportportal/service/LaunchImpl.java b/src/main/java/com/epam/reportportal/service/LaunchImpl.java index 9a85175b..8b7e5883 100644 --- a/src/main/java/com/epam/reportportal/service/LaunchImpl.java +++ b/src/main/java/com/epam/reportportal/service/LaunchImpl.java @@ -446,13 +446,21 @@ public Maybe finishTestItem(final Maybe item, fin getStepReporter().finishPreviousStep(ofNullable(rq.getStatus()).map(ItemStatus::valueOf).orElse(null)); ItemStatus status = ofNullable(rq.getStatus()).map(ItemStatus::valueOf).orElse(null); - if (status == ItemStatus.FAILED || (status == ItemStatus.SKIPPED && getParameters().getSkippedAnIssue())) { - completeBtsIssues(rq.getIssue()); - } else if (status == ItemStatus.SKIPPED && !getParameters().getSkippedAnIssue()) { - rq.setIssue(Launch.NOT_ISSUE); - } else if (status == ItemStatus.PASSED && rq.getIssue() != null && getParameters().isBtsIssueFail()) { - rq.setStatus(ItemStatus.FAILED.name()); - rq.setIssue(StaticStructuresUtils.REDUNDANT_ISSUE); + if (rq.getIssue() == null) { + if (status == ItemStatus.SKIPPED && !getParameters().getSkippedAnIssue()) { + rq.setIssue(Launch.NOT_ISSUE); + } + } else { + if (status == ItemStatus.FAILED || (status == ItemStatus.SKIPPED && getParameters().getSkippedAnIssue())) { + completeBtsIssues(rq.getIssue()); + } else if (status == ItemStatus.PASSED) { + if (getParameters().isBtsIssueFail()) { + rq.setStatus(ItemStatus.FAILED.name()); + rq.setIssue(StaticStructuresUtils.REDUNDANT_ISSUE); + } else { + rq.setIssue(null); + } + } } QUEUE.getOrCompute(launch).addToQueue(LoggingContext.complete()); From 8354ec4d3caad2397d173e979440e2368f28ea76 Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Wed, 6 Nov 2024 16:27:07 +0300 Subject: [PATCH 2/4] Fix test --- src/test/java/com/epam/reportportal/service/LaunchTest.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/test/java/com/epam/reportportal/service/LaunchTest.java b/src/test/java/com/epam/reportportal/service/LaunchTest.java index 955813de..e575fb50 100644 --- a/src/test/java/com/epam/reportportal/service/LaunchTest.java +++ b/src/test/java/com/epam/reportportal/service/LaunchTest.java @@ -563,11 +563,7 @@ public void verify_not_failing_item_with_issue_on_passed_test_if_it_turned_off() verify(rpClient).finishTestItem(eq(itemId.blockingGet()), captor.capture()); FinishTestItemRQ resultFinishRq = captor.getValue(); - assertThat(resultFinishRq.getIssue(), notNullValue()); - Issue issue = resultFinishRq.getIssue(); - assertThat(issue.getIssueType(), nullValue()); - assertThat(issue.getComment(), nullValue()); - assertThat(issue.getExternalSystemIssues(), nullValue()); + assertThat(resultFinishRq.getIssue(), nullValue()); } @Test From 95c6fc0421b02f0a3750846ee49f9ef5a6a22e7d Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Fri, 8 Nov 2024 10:03:03 +0300 Subject: [PATCH 3/4] Update README.md --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index b65b637c..96b0c97f 100644 --- a/README.md +++ b/README.md @@ -156,6 +156,15 @@ etc. | rp.truncation.item.name.limit | Integer | Default: `1024`
Maximum item names length before truncation. | | rp.truncation.attribute.limit | Integer | Default: `128`
Maximum attribute key and value limit (counts separately) | +### Bug Tracking System parameters + +| **Property name** | **Type** | **Description** | +|-------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| rp.bts.project | String | Bug Tracking System Project name to use along with `@ExternalIssue` annotation. Should be the same as in corresponding integration. | +| rp.bts.url | String | Bug Tracking System base URL. Should be the same as in corresponding integration. | +| rp.bts.issue.url | String | Bug Tracking System URL Pattern for Issues. Use {issue_id} and {bts_project} placeholders to mark a place where to put Issue ID and Bug Tracking System Project name. | +| rp.bts.issue.fail | Boolean | Default: `true`
Fail tests marked with `@Issue` annotation if they passed. Designed to not miss the moment when the issue got fixed but test is still marked by annotation. | + ## Proxy configuration ReportPortal supports 2 options for setting Proxy configuration: From 2f1b042f83cc8dc27c27b51626fb21c97b9a10e6 Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Fri, 8 Nov 2024 16:51:43 +0300 Subject: [PATCH 4/4] Issue Locator lookup by value in `@Issue` annotation --- CHANGELOG.md | 2 + .../epam/reportportal/service/LaunchImpl.java | 85 +++++++++----- .../epam/reportportal/service/LaunchTest.java | 109 ++++++++++++++++++ .../com/epam/reportportal/test/TestUtils.java | 55 +++++++++ 4 files changed, 219 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34c2055d..04dd84fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ ## [Unreleased] ### Fixed - `@Issue` and `@Issues` annotations handling in certain cases, by @HardNorth +### Added +- Issue Locator lookup by value in `@Issue` annotation, by @HardNorth ## [5.2.19] ### Added diff --git a/src/main/java/com/epam/reportportal/service/LaunchImpl.java b/src/main/java/com/epam/reportportal/service/LaunchImpl.java index 8b7e5883..c9f4564d 100644 --- a/src/main/java/com/epam/reportportal/service/LaunchImpl.java +++ b/src/main/java/com/epam/reportportal/service/LaunchImpl.java @@ -29,6 +29,7 @@ import com.epam.ta.reportportal.ws.model.item.ItemCreatedRS; import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ; import com.epam.ta.reportportal.ws.model.launch.StartLaunchRS; +import com.epam.ta.reportportal.ws.model.project.config.ProjectSettingsResource; import io.reactivex.*; import io.reactivex.functions.Consumer; import io.reactivex.functions.Function; @@ -72,17 +73,15 @@ public class LaunchImpl extends Launch { private static final int ITEM_FINISH_RETRY_TIMEOUT = 10; private static final Predicate INTERNAL_CLIENT_EXCEPTION_PREDICATE = throwable -> throwable instanceof InternalReportPortalClientException; - private static final Predicate TEST_ITEM_FINISH_RETRY_PREDICATE = throwable -> - (throwable instanceof ReportPortalException - && ErrorType.FINISH_ITEM_NOT_ALLOWED.equals(((ReportPortalException) throwable).getError() - .getErrorType())) || INTERNAL_CLIENT_EXCEPTION_PREDICATE.test(throwable); + private static final Predicate TEST_ITEM_FINISH_RETRY_PREDICATE = throwable -> (throwable instanceof ReportPortalException + && ErrorType.FINISH_ITEM_NOT_ALLOWED.equals(((ReportPortalException) throwable).getError().getErrorType())) + || INTERNAL_CLIENT_EXCEPTION_PREDICATE.test(throwable); private static final RetryWithDelay DEFAULT_REQUEST_RETRY = new RetryWithDelay(INTERNAL_CLIENT_EXCEPTION_PREDICATE, DEFAULT_RETRY_COUNT, TimeUnit.SECONDS.toMillis(DEFAULT_RETRY_TIMEOUT) ); - private static final RetryWithDelay TEST_ITEM_FINISH_REQUEST_RETRY = new RetryWithDelay( - TEST_ITEM_FINISH_RETRY_PREDICATE, + private static final RetryWithDelay TEST_ITEM_FINISH_REQUEST_RETRY = new RetryWithDelay(TEST_ITEM_FINISH_RETRY_PREDICATE, ITEM_FINISH_MAX_RETRIES, TimeUnit.SECONDS.toMillis(ITEM_FINISH_RETRY_TIMEOUT) ); @@ -101,14 +100,14 @@ public class LaunchImpl extends Launch { protected final ComputationConcurrentHashMap QUEUE = new ComputationConcurrentHashMap(); protected final Maybe launch; + protected final StartLaunchRQ startRq; + protected final Maybe projectSettings; private final ExecutorService executor; private final Scheduler scheduler; private StatisticsService statisticsService; - private final StartLaunchRQ startRq; - protected LaunchImpl(@Nonnull final ReportPortalClient reportPortalClient, - @Nonnull final ListenerParameters parameters, @Nonnull final StartLaunchRQ rq, - @Nonnull final ExecutorService executorService) { + protected LaunchImpl(@Nonnull final ReportPortalClient reportPortalClient, @Nonnull final ListenerParameters parameters, + @Nonnull final StartLaunchRQ rq, @Nonnull final ExecutorService executorService) { super(reportPortalClient, parameters); requireNonNull(parameters, "Parameters shouldn't be NULL"); executor = requireNonNull(executorService); @@ -133,11 +132,12 @@ protected LaunchImpl(@Nonnull final ReportPortalClient reportPortalClient, emitter.onComplete(); }); }).cache(); + projectSettings = ofNullable(getClient().getProjectSettings()).map(settings -> settings.subscribeOn(getScheduler()).cache()) + .orElse(Maybe.empty()); } - protected LaunchImpl(@Nonnull final ReportPortalClient reportPortalClient, - @Nonnull final ListenerParameters parameters, @Nonnull final Maybe launchMaybe, - @Nonnull final ExecutorService executorService) { + protected LaunchImpl(@Nonnull final ReportPortalClient reportPortalClient, @Nonnull final ListenerParameters parameters, + @Nonnull final Maybe launchMaybe, @Nonnull final ExecutorService executorService) { super(reportPortalClient, parameters); requireNonNull(parameters, "Parameters shouldn't be NULL"); executor = requireNonNull(executorService); @@ -147,14 +147,13 @@ protected LaunchImpl(@Nonnull final ReportPortalClient reportPortalClient, LOGGER.info("Rerun: {}", parameters.isRerun()); launch = launchMaybe.cache(); + projectSettings = ofNullable(getClient().getProjectSettings()).map(settings -> settings.subscribeOn(getScheduler()).cache()) + .orElse(Maybe.empty()); } private static StartLaunchRQ emptyStartLaunchForStatistics() { StartLaunchRQ result = new StartLaunchRQ(); - result.setAttributes(Collections.singleton(new ItemAttributesRQ(DefaultProperties.AGENT.getName(), - CUSTOM_AGENT, - true - ))); + result.setAttributes(Collections.singleton(new ItemAttributesRQ(DefaultProperties.AGENT.getName(), CUSTOM_AGENT, true))); return result; } @@ -214,8 +213,7 @@ private Set truncateAttributes(@Nullable final Set limit && keyLength > replacement.length()) { - updated = new ItemAttributesRQ( - updated.getKey().substring(0, limit - replacement.length()) + replacement, + updated = new ItemAttributesRQ(updated.getKey().substring(0, limit - replacement.length()) + replacement, updated.getValue(), updated.isSystem() ); @@ -249,11 +247,11 @@ private void truncateAttributes(@Nonnull final FinishExecutionRQ rq) { protected Maybe start(boolean statistics) { launch.subscribe(logMaybeResults("Launch start")); ListenerParameters params = getParameters(); - if(params.isPrintLaunchUuid()) { + if (params.isPrintLaunchUuid()) { launch.subscribe(printLaunch(params)); } LaunchLoggingContext.init(this.launch, getClient(), getScheduler(), getParameters()); - if(statistics) { + if (statistics) { getStatisticsService().sendEvent(launch, startRq); } return launch; @@ -322,10 +320,7 @@ public Maybe startTestItem(final StartTestItemRQ request) { Maybe item = launch.flatMap((Function>) launchId -> { rq.setLaunchUuid(launchId); - return getClient().startTestItem(rq) - .retry(DEFAULT_REQUEST_RETRY) - .doOnSuccess(logCreated("item")) - .map(TO_ID); + return getClient().startTestItem(rq).retry(DEFAULT_REQUEST_RETRY).doOnSuccess(logCreated("item")).map(TO_ID); }).cache(); item.subscribeOn(getScheduler()).subscribe(logMaybeResults("Start test item")); @@ -345,8 +340,7 @@ public Maybe startTestItem(final StartTestItemRQ request) { * @return Test Item ID promise */ @Nonnull - public Maybe startTestItem(final Maybe parentId, final Maybe retryOf, - final StartTestItemRQ rq) { + public Maybe startTestItem(final Maybe parentId, final Maybe retryOf, final StartTestItemRQ rq) { return retryOf.flatMap((Function>) s -> startTestItem(parentId, rq)).cache(); } @@ -389,8 +383,35 @@ public Maybe startTestItem(final Maybe parentId, final StartTest return item; } - protected void completeBtsIssues(@Nullable Issue issue) { - if(!ofNullable(issue).map(Issue::getExternalSystemIssues).filter(issues -> !issues.isEmpty()).isPresent()) { + /** + * Lookup for the Issue Type locator in project settings and fill missed external issue fields based on properties. + * + * @param issue Issue to complete + */ + protected void completeIssues(@Nonnull Issue issue) { + String issueType = issue.getIssueType(); + if (StringUtils.isBlank(issueType)) { + return; + } + ofNullable(projectSettings.blockingGet()).map(ProjectSettingsResource::getSubTypes) + .ifPresent(subTypes -> subTypes.values().stream().flatMap(List::stream).forEach(value -> { + if (issueType.equals(value.getLocator())) { + return; + } + if (issueType.equalsIgnoreCase(value.getShortName())) { + issue.setIssueType(value.getLocator()); + return; + } + if (issueType.equalsIgnoreCase(value.getLongName())) { + issue.setIssueType(value.getLocator()); + return; + } + if (issueType.equals(value.getTypeRef())) { + issue.setIssueType(value.getLocator()); + } + })); + + if (!ofNullable(issue.getExternalSystemIssues()).filter(issues -> !issues.isEmpty()).isPresent()) { return; } ListenerParameters params = getParameters(); @@ -398,7 +419,7 @@ protected void completeBtsIssues(@Nullable Issue issue) { Optional btsProjectId = ofNullable(params.getBtsProjectId()).filter(StringUtils::isNotBlank); Optional btsIssueUrl = ofNullable(params.getBtsIssueUrl()).filter(StringUtils::isNotBlank); issue.getExternalSystemIssues().stream().filter(Objects::nonNull).forEach(externalIssue -> { - if(StringUtils.isBlank(externalIssue.getTicketId())) { + if (StringUtils.isBlank(externalIssue.getTicketId())) { return; } if (btsUrl.isPresent() && StringUtils.isBlank(externalIssue.getBtsUrl())) { @@ -452,7 +473,7 @@ public Maybe finishTestItem(final Maybe item, fin } } else { if (status == ItemStatus.FAILED || (status == ItemStatus.SKIPPED && getParameters().getSkippedAnIssue())) { - completeBtsIssues(rq.getIssue()); + completeIssues(rq.getIssue()); } else if (status == ItemStatus.PASSED) { if (getParameters().isBtsIssueFail()) { rq.setStatus(ItemStatus.FAILED.name()); @@ -531,7 +552,7 @@ public Maybe getParent() { } } - protected static class ComputationConcurrentHashMap extends ConcurrentHashMap, LaunchImpl.TreeItem> { + protected static class ComputationConcurrentHashMap extends ConcurrentHashMap, LaunchImpl.TreeItem> { public LaunchImpl.TreeItem getOrCompute(Maybe key) { return computeIfAbsent(key, k -> new LaunchImpl.TreeItem()); } diff --git a/src/test/java/com/epam/reportportal/service/LaunchTest.java b/src/test/java/com/epam/reportportal/service/LaunchTest.java index e575fb50..62ea4adb 100644 --- a/src/test/java/com/epam/reportportal/service/LaunchTest.java +++ b/src/test/java/com/epam/reportportal/service/LaunchTest.java @@ -60,6 +60,7 @@ import static com.epam.reportportal.util.test.CommonUtils.shutdownExecutorService; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.endsWith; +import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -642,4 +643,112 @@ public void verify_external_issue_url_is_used_for_project_and_ticket_ids() { Issue.ExternalSystemIssue resultExternalIssue = resultFinishRq.getIssue().getExternalSystemIssues().iterator().next(); assertThat(resultExternalIssue.getUrl(), equalTo("https://test.com/example_project/issue/RP-001")); } + + @Test + public void verify_issue_type_lookup_by_locator() { + simulateStartLaunchResponse(rpClient); + simulateStartTestItemResponse(rpClient); + simulateFinishTestItemResponse(rpClient); + when(rpClient.getProjectSettings()).thenReturn(Maybe.just(standardProjectSettings())); + + Launch launch = createLaunch(standardParameters()); + String launchUuid = launch.start().blockingGet(); + StartTestItemRQ itemRq = standardStartStepRequest(); + itemRq.setLaunchUuid(launchUuid); + Maybe itemId = launch.startTestItem(itemRq); + FinishTestItemRQ finishRq = positiveFinishRequest(); + finishRq.setStatus(ItemStatus.FAILED.name()); + Issue issue = new Issue(); + issue.setIssueType("pb001"); + finishRq.setIssue(issue); + launch.finishTestItem(itemId, finishRq).blockingGet(); + + ArgumentCaptor captor = ArgumentCaptor.forClass(FinishTestItemRQ.class); + verify(rpClient).finishTestItem(eq(itemId.blockingGet()), captor.capture()); + + FinishTestItemRQ resultFinishRq = captor.getValue(); + assertThat(resultFinishRq.getIssue(), notNullValue()); + assertThat(resultFinishRq.getIssue().getIssueType(), equalTo("pb001")); + } + + @Test + public void verify_issue_type_lookup_by_short_name() { + simulateStartLaunchResponse(rpClient); + simulateStartTestItemResponse(rpClient); + simulateFinishTestItemResponse(rpClient); + when(rpClient.getProjectSettings()).thenReturn(Maybe.just(standardProjectSettings())); + + Launch launch = createLaunch(standardParameters()); + String launchUuid = launch.start().blockingGet(); + StartTestItemRQ itemRq = standardStartStepRequest(); + itemRq.setLaunchUuid(launchUuid); + Maybe itemId = launch.startTestItem(itemRq); + FinishTestItemRQ finishRq = positiveFinishRequest(); + finishRq.setStatus(ItemStatus.FAILED.name()); + Issue issue = new Issue(); + issue.setIssueType("ab"); + finishRq.setIssue(issue); + launch.finishTestItem(itemId, finishRq).blockingGet(); + + ArgumentCaptor captor = ArgumentCaptor.forClass(FinishTestItemRQ.class); + verify(rpClient).finishTestItem(eq(itemId.blockingGet()), captor.capture()); + + FinishTestItemRQ resultFinishRq = captor.getValue(); + assertThat(resultFinishRq.getIssue(), notNullValue()); + assertThat(resultFinishRq.getIssue().getIssueType(), equalTo("ab001")); + } + + @Test + public void verify_issue_type_lookup_by_long_name() { + simulateStartLaunchResponse(rpClient); + simulateStartTestItemResponse(rpClient); + simulateFinishTestItemResponse(rpClient); + when(rpClient.getProjectSettings()).thenReturn(Maybe.just(standardProjectSettings())); + + Launch launch = createLaunch(standardParameters()); + String launchUuid = launch.start().blockingGet(); + StartTestItemRQ itemRq = standardStartStepRequest(); + itemRq.setLaunchUuid(launchUuid); + Maybe itemId = launch.startTestItem(itemRq); + FinishTestItemRQ finishRq = positiveFinishRequest(); + finishRq.setStatus(ItemStatus.FAILED.name()); + Issue issue = new Issue(); + issue.setIssueType("system issue"); + finishRq.setIssue(issue); + launch.finishTestItem(itemId, finishRq).blockingGet(); + + ArgumentCaptor captor = ArgumentCaptor.forClass(FinishTestItemRQ.class); + verify(rpClient).finishTestItem(eq(itemId.blockingGet()), captor.capture()); + + FinishTestItemRQ resultFinishRq = captor.getValue(); + assertThat(resultFinishRq.getIssue(), notNullValue()); + assertThat(resultFinishRq.getIssue().getIssueType(), equalTo("si001")); + } + + @Test + public void verify_issue_type_lookup_by_type_reference() { + simulateStartLaunchResponse(rpClient); + simulateStartTestItemResponse(rpClient); + simulateFinishTestItemResponse(rpClient); + when(rpClient.getProjectSettings()).thenReturn(Maybe.just(standardProjectSettings())); + + Launch launch = createLaunch(standardParameters()); + String launchUuid = launch.start().blockingGet(); + StartTestItemRQ itemRq = standardStartStepRequest(); + itemRq.setLaunchUuid(launchUuid); + Maybe itemId = launch.startTestItem(itemRq); + FinishTestItemRQ finishRq = positiveFinishRequest(); + finishRq.setStatus(ItemStatus.FAILED.name()); + Issue issue = new Issue(); + issue.setIssueType("NO_DEFECT"); + finishRq.setIssue(issue); + launch.finishTestItem(itemId, finishRq).blockingGet(); + + ArgumentCaptor captor = ArgumentCaptor.forClass(FinishTestItemRQ.class); + verify(rpClient).finishTestItem(eq(itemId.blockingGet()), captor.capture()); + + FinishTestItemRQ resultFinishRq = captor.getValue(); + assertThat(resultFinishRq.getIssue(), notNullValue()); + assertThat(resultFinishRq.getIssue().getIssueType(), equalTo("nd001")); + } } diff --git a/src/test/java/com/epam/reportportal/test/TestUtils.java b/src/test/java/com/epam/reportportal/test/TestUtils.java index e0d97683..eecdc579 100644 --- a/src/test/java/com/epam/reportportal/test/TestUtils.java +++ b/src/test/java/com/epam/reportportal/test/TestUtils.java @@ -24,6 +24,8 @@ import com.epam.ta.reportportal.ws.model.launch.StartLaunchRQ; import com.epam.ta.reportportal.ws.model.launch.StartLaunchRS; import com.epam.ta.reportportal.ws.model.log.SaveLogRQ; +import com.epam.ta.reportportal.ws.model.project.config.IssueSubTypeResource; +import com.epam.ta.reportportal.ws.model.project.config.ProjectSettingsResource; import com.fasterxml.jackson.core.type.TypeReference; import io.reactivex.Maybe; import okhttp3.MultipartBody; @@ -61,6 +63,59 @@ public static ListenerParameters standardParameters() { return result; } + public static ProjectSettingsResource standardProjectSettings() { + ProjectSettingsResource settings = new ProjectSettingsResource(); + settings.setProjectId(2L); + HashMap> subTypes = new HashMap<>(); + settings.setSubTypes(subTypes); + IssueSubTypeResource subType = new IssueSubTypeResource(); + subType.setId(1L); + subType.setLocator("ti001"); + subType.setTypeRef("TO_INVESTIGATE"); + subType.setLongName("To Investigate"); + subType.setShortName("TI"); + subType.setColor("#00829b"); + subTypes.computeIfAbsent(subType.getTypeRef(), k -> new ArrayList<>()).add(subType); + + subType = new IssueSubTypeResource(); + subType.setId(2L); + subType.setLocator("ab001"); + subType.setTypeRef("AUTOMATION_BUG"); + subType.setLongName("Automation Bug"); + subType.setShortName("AB"); + subType.setColor("#ffc208"); + subTypes.computeIfAbsent(subType.getTypeRef(), k -> new ArrayList<>()).add(subType); + + subType = new IssueSubTypeResource(); + subType.setId(3L); + subType.setLocator("pb001"); + subType.setTypeRef("PRODUCT_BUG"); + subType.setLongName("Product Bug"); + subType.setShortName("PB"); + subType.setColor("#d32f2f"); + subTypes.computeIfAbsent(subType.getTypeRef(), k -> new ArrayList<>()).add(subType); + + subType = new IssueSubTypeResource(); + subType.setId(4L); + subType.setLocator("nd001"); + subType.setTypeRef("NO_DEFECT"); + subType.setLongName("No Defect"); + subType.setShortName("ND"); + subType.setColor("#76839b"); + subTypes.computeIfAbsent(subType.getTypeRef(), k -> new ArrayList<>()).add(subType); + + subType = new IssueSubTypeResource(); + subType.setId(5L); + subType.setLocator("si001"); + subType.setTypeRef("SYSTEM_ISSUE"); + subType.setLongName("System Issue"); + subType.setShortName("SI"); + subType.setColor("#3e7be6"); + subTypes.computeIfAbsent(subType.getTypeRef(), k -> new ArrayList<>()).add(subType); + + return settings; + } + public static Maybe startLaunchResponse(String id) { final StartLaunchRS rs = new StartLaunchRS(); rs.setId(id);