Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
4768c7b
Initial TMS migration
imashkanov Feb 18, 2025
501098e
Integration and Unit Tests for existing Controllers
konstantinshaplyko Feb 24, 2025
2923441
Implementation of tms_test_plan CRUD
imashkanov Mar 19, 2025
487469d
fix existing integration tests
konstantinshaplyko Mar 13, 2025
7875757
Integration Tests for existing Controllers
konstantinshaplyko Mar 17, 2025
c78db4e
Implement controller and integration tests for datasets
imashkanov Mar 14, 2025
8cf662d
adjust product version API
konstantinshaplyko Mar 28, 2025
ac3cc9d
Add dataset to environment API
imashkanov Mar 28, 2025
9ebae2d
Adjust Test Case API
imashkanov Mar 28, 2025
1ec9e78
Feature/orgs changes
imashkanov Apr 3, 2025
e567c0a
Checkstyle: changed intends from 4 to 2 and added javaDocs
imashkanov Apr 6, 2025
83ca240
Adjust controllers paths to support new orgs functionality
imashkanov Apr 15, 2025
e3c6f49
Adjust controllers paths to support new orgs functionality - fix revi…
konstantinshaplyko Apr 16, 2025
7597204
Re-group existing controllers
konstantinshaplyko Apr 25, 2025
a9c12d5
add CRUD API for test folders + support subfolders
imashkanov Apr 25, 2025
3033829
Rebase latest feature/orgs: Before rebase service api with rebased mi…
imashkanov May 22, 2025
4368a99
Rebase latest feature/orgs: After rebase service api with rebased mig…
imashkanov May 22, 2025
82aa10b
Add mapping schema for QASpace test cases for import
imashkanov May 16, 2025
f642320
Create Tms Test Case Controller Stubs according to API design
imashkanov Jun 9, 2025
ad8cf80
TmsTestCase: Batch delete and batch patch operations (#2306)
imashkanov Jun 18, 2025
5786bc3
TmsTestFolder API enhancements
imashkanov Jun 18, 2025
9f7a4d2
TmsTestCase enhancements
imashkanov Jun 26, 2025
1a0971c
After rebase onto develop + feature/orgs
imashkanov Jul 8, 2025
3b6eef2
Test Case Contract refactoring
imashkanov Jul 10, 2025
869a390
Fix the issue with 404 when returning test folders in the empty project
imashkanov Jul 21, 2025
de67506
Test Case Full-text search by name, description and priority
imashkanov Jul 15, 2025
797bc14
Add /v1 to all tms apis
imashkanov Jul 22, 2025
81a4d01
Make tms-steps not-mandatory in the create test-case request
imashkanov Jul 28, 2025
53b71a7
Add external_id to TmsTestCase
imashkanov Jul 26, 2025
3a02500
Add relations between RPP-schema and TMS
imashkanov Jul 26, 2025
d67b6d4
Enhance batch patch operation with priority and tags
imashkanov Jul 27, 2025
7e532e8
Add tms-controllers to global error handling
imashkanov Jul 30, 2025
7a50096
Fix project extractor for TMS endpoints
imashkanov Jul 31, 2025
90b91dd
Split manual scenario to TEXT and STEPS
imashkanov Aug 6, 2025
7fb7c33
Refactoring of the tags-attributes implementation
imashkanov Aug 18, 2025
1877960
Add created_at and updated_at to TmsTestCase
imashkanov Aug 18, 2025
e7ae4c8
Add "delete tag from test case" and "batch delete tags from test case…
imashkanov Aug 19, 2025
c5fc287
Enahnce test plans: part 1
imashkanov Aug 21, 2025
8434dd5
Enahnce test plans - part 2: add search test cases by test plan
imashkanov Aug 22, 2025
1574e8b
Enahnce test plans - part 3: add search of test folders by test plan
imashkanov Aug 22, 2025
7722b68
Enahnce test plans - part 4: fix removing of test plans and mapping o…
imashkanov Aug 22, 2025
61e75ae
Enahnce test plans - part 5: add capability of bulk adding and remova…
imashkanov Aug 23, 2025
eae485b
Enhance import of test cases - make test folder mandatory part
imashkanov Aug 24, 2025
bf20f51
Improve tms test case and test folder contract regarding parent test …
imashkanov Aug 26, 2025
629e944
After rebase
imashkanov Aug 29, 2025
2e84198
Batch duplicate test cases
imashkanov Aug 27, 2025
564897a
TMS Attributes management: 1 part - returning to the usage of ids in …
imashkanov Sep 3, 2025
3ec1d1e
TMS Attributes management: 2 part - batch patch test case attributes
imashkanov Sep 4, 2025
794188a
TMS Attributes management: 3 part - tms attributes api
imashkanov Sep 7, 2025
ac72e15
Make "add" and "remove" test cases to\from test plan working in a bat…
imashkanov Sep 16, 2025
3bd1289
Add full-text search to test-plan
imashkanov Sep 16, 2025
8bfd5c5
Tms Attachment implementation
imashkanov Sep 18, 2025
a21a1d6
Move tms attachments to separate bucket
imashkanov Sep 25, 2025
d08fe4f
Move tms dao layer to commons-dao
imashkanov Sep 30, 2025
22c05e8
Add Offset argument resolver
imashkanov Sep 30, 2025
4a606fc
Add pagination, filtering and sorting for test case, test folder and …
imashkanov Oct 2, 2025
62ff0e5
Add full-text search for tms attribute
imashkanov Oct 6, 2025
9d57e84
After rebase
imashkanov Oct 15, 2025
ae0579a
Add the contract of test plan execution statistic
imashkanov Oct 14, 2025
d94c8a8
Add the contract of test case execution statistic
imashkanov Oct 15, 2025
65b166d
Add the contract of test plan duplication
imashkanov Oct 15, 2025
5543449
Added test plan execution statistic
imashkanov Oct 15, 2025
0464948
Added TMS Manual Launch Contracts
imashkanov Oct 16, 2025
920fe49
TmsTestCaseExecution: Added last execution to TmsTestCaseRS
imashkanov Oct 18, 2025
48585af
Added duplicate test plan functionality
imashkanov Oct 20, 2025
77b1d81
Enhanced duplicate test plan functionality
imashkanov Oct 24, 2025
9d9bb0f
Remove get subfolders api and subfolders from TmsTestFolderRS
imashkanov Oct 24, 2025
f35a883
Added duplicate test folder api
imashkanov Oct 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ hs_err_pid*
build/
.gradle/
out/
src/test/resources/db/migration/*.sql
6 changes: 6 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ dependencies {

// JasperReport's export to XLS uses Apache POI and openpdf for PDF export
implementation(libs.apache.poi)
implementation(libs.apache.poi.ooxml)
implementation(libs.apache.commons.commonscsv)
implementation(libs.openpdf)
implementation(libs.jakarta.inject.api)
implementation(libs.jakarta.mail)
Expand All @@ -112,6 +114,10 @@ dependencies {
compileOnly(libs.lombok)
annotationProcessor(libs.lombok)

//mapstruct
implementation(libs.mapstruct)
annotationProcessor(libs.mapstruct.processor)

// Tests
testImplementation(libs.bundles.test.libs)
testCompileOnly(libs.lombok)
Expand Down
15 changes: 15 additions & 0 deletions doc/importFromQASpace.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
| Source QASpace Field | Target TMS Entity and Field | Mapping Schema |
| :-- | :-- | :-- |
| path | TmsTestFolder hierarchy | The path string is split by the separator / and a folder hierarchy is created in TmsTestFolder. The last folder in the hierarchy will contain the test case. |
| priority | TmsTestCase.priority | New field that needs to be added to TmsTestCase. Possible values: "Minor", "Major", "Critical", "Blocker". |
| summary | TmsTestCase.name | Direct mapping to the name field. |
| test steps | TmsTestCaseVersion.manualScenario.steps[].instructions | Text from the "test steps" field needs to be split into separate steps and create a record in TmsStep for each step, filling the instructions field. |
| expected result | TmsTestCaseVersion.manualScenario.steps[].expectedResult | Text from the "expected result" field needs to be split into separate expected results corresponding to the steps, and fill the expectedResult field for each step. |
| status | New field in manual execution | Do not map for now (will be added later). |
| test type | New field in manual execution | Do not map for now (will be added later). |
| description | TmsTestCase.description | Direct mapping to the description field. |
| labels | TmsTestCase.tags | For each value in the "labels" field, create a record inTmsAttribute with key == "label" and link through TmsTestCaseAttribute |
| components | Do not map | According to requirements, no need to import. |
| versions | Do not map | According to requirements, no need to import. |
| bugs (not imported) | Do not map | According to requirements, no need to import. |
| requirements | TmsTestCaseVersion.manualScenario.linkToRequirements | Direct mapping to the linkToRequirements field. |
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ dockerJavaOptsDev=-DLOG_FILE=app.log \
-Djava.security.egd=file:/dev/./urandom \
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
dockerServerUrl=unix:///var/run/docker.sock
org.gradle.jvmargs=-Xmx2048m
org.gradle.jvmargs=-Xmx2048m
10 changes: 9 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[versions]
# Development versions
commons-dev = "f7c7d2c"
commons-dao-dev = "f7ac74d"
commons-dao-dev = "accffcbc73"
plugin-api-dev = "87b8788"

# Platform versions
Expand Down Expand Up @@ -37,6 +37,8 @@ lombok = "1.18.36"
jooq = "3.19.18"
jclouds = "2.6.0"
hibernate-validator = "8.0.2.Final"
mapstruct = "1.5.5.Final"
apache-commons-csv = "1.10.0"

[libraries]
# Development libs
Expand Down Expand Up @@ -80,6 +82,7 @@ rabbitmq-http-client = { group = "com.rabbitmq", name = "http-client", version.r
httpclient5 = { group = "org.apache.httpcomponents.client5", name = "httpclient5", version.ref = "httpclient5" }
jasperreports = { group = "net.sf.jasperreports", name = "jasperreports", version.ref = "jasperreports" }
apache-poi = { group = "org.apache.poi", name = "poi", version.ref = "apache-poi" }
apache-poi-ooxml = { group = "org.apache.poi", name = "poi-ooxml", version.ref = "apache-poi" }
openpdf = { group = "com.github.librepdf", name = "openpdf", version.ref = "openpdf" }
jakarta-inject-api = { group = "jakarta.inject", name = "jakarta.inject-api", version.ref = "jakarta-inject" }
jakarta-mail = { group = "com.sun.mail", name = "jakarta.mail", version.ref = "jakarta-mail" }
Expand All @@ -92,10 +95,15 @@ apache-commons-compress = { group = "org.apache.commons", name = "commons-compre
hibernate-validator = { group = "org.hibernate.validator", name = "hibernate-validator", version.ref = "hibernate-validator" }
json-schema-validator = { group = "com.networknt", name = "json-schema-validator", version.ref = "json-schema-validator" }
caffeine = { group = "com.github.ben-manes.caffeine", name = "caffeine" }
apache-commons-commonscsv = { group = "org.apache.commons", name = "commons-csv", version.ref = "apache-commons-csv" }

# Lombok
lombok = { group = "org.projectlombok", name = "lombok", version.ref = "lombok" }

# Mapstruct
mapstruct = { group = "org.mapstruct", name = "mapstruct", version.ref = "mapstruct" }
mapstruct-processor = { group = "org.mapstruct", name = "mapstruct-processor", version.ref = "mapstruct" }

# Test libraries
spring-test = { group = "org.springframework", name = "spring-test" }
flyway-spring-test = { group = "org.flywaydb.flyway-test-extensions", name = "flyway-spring-test", version.ref = "flyway-spring-test" }
Expand Down
3 changes: 2 additions & 1 deletion project-properties.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ project.ext {
isDebugMode = System.getProperty("DEBUG", "false") == "true"
releaseMode = project.hasProperty("releaseMode") ? project.releaseMode.toBoolean() : false
scriptsUrl = commonScriptsUrl + (releaseMode ? '5.14.0' : 'develop')
migrationsUrl = migrationsScriptsUrl + (releaseMode ? '5.14.0' : 'develop')
migrationsUrl = migrationsScriptsUrl + (releaseMode ? '5.14.0' : 'feature/EPMRPP-migrate-tms-to-develop')
manifestSchemaUrl = schemaUrl + ('manifest.schema.json')
//TODO refactor with archive download
testScriptsSrc = [
Expand Down Expand Up @@ -78,6 +78,7 @@ project.ext {
(migrationsUrl + '/migrations/96_create_groups_tables.up.sql') : 'V096__create_groups_tables.sql',
(migrationsUrl + '/migrations/97_add_groups_uuid.up.sql') : 'V097__add_groups_uuid.up.sql',
(migrationsUrl + '/migrations/98_add_plugin_type.up.sql') : 'V098__add_plugin_type.up.sql',
(migrationsUrl + '/migrations/103_tms_initial.up.sql') : 'V103__tms_initial.up.sql',
(migrationsUrl + '/migrations/198_add_slugify_function.up.sql') : 'V198__add_slugify_function.sql',
(migrationsUrl + '/migrations/199_organization_tables.up.sql') : 'V199__organization_tables.sql',
(migrationsUrl + '/migrations/200_migrate_org_roles.up.sql') : 'V200__migrate_org_roles.sql',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.epam.ta.reportportal.ws.resolver.ActiveUserWebArgumentResolver;
import com.epam.ta.reportportal.ws.resolver.FilterCriteriaResolver;
import com.epam.ta.reportportal.ws.resolver.JsonViewSupportFactoryBean;
import com.epam.ta.reportportal.ws.resolver.OffsetArgumentResolver;
import com.epam.ta.reportportal.ws.resolver.PagingHandlerMethodArgumentResolver;
import com.epam.ta.reportportal.ws.resolver.PredefinedFilterCriteriaResolver;
import com.epam.ta.reportportal.ws.resolver.SortArgumentResolver;
Expand Down Expand Up @@ -97,6 +98,7 @@ public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentRes
argumentResolvers.add(new ActiveUserWebArgumentResolver());
argumentResolvers.add(new FilterCriteriaResolver());
argumentResolvers.add(new PredefinedFilterCriteriaResolver());
argumentResolvers.add(new OffsetArgumentResolver());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package com.epam.ta.reportportal.core.configs;

import com.epam.reportportal.extension.classloader.ReportPortalResourceLoader;
import com.epam.ta.reportportal.core.tms.scheduled.TmsAttachmentCleanupJob;
import com.epam.ta.reportportal.job.CleanExpiredCreationBidsJob;
import com.epam.ta.reportportal.job.FlushingDataJob;
import com.epam.ta.reportportal.job.InterruptBrokenLaunchesJob;
Expand Down Expand Up @@ -70,6 +71,9 @@ public class SchedulerConfiguration {
@Autowired
private ReportPortalResourceLoader resourceLoader;

@Autowired
private TmsAttachmentCleanupJob tmsAttachmentCleanupJob;

@Bean
@Primary
public SchedulerFactoryBean schedulerFactoryBean() {
Expand Down Expand Up @@ -162,6 +166,18 @@ public SimpleTriggerFactoryBean createTrigger(JobDetail jobDetail, long pollFreq
return factoryBean;
}

@Bean
public SimpleTriggerFactoryBean tmsAttachmentCleanupTrigger(
@Named("tmsAttachmentCleanupJobBean") JobDetail jobDetail,
@Value("${rp.tms.attachment.cleanup.cleanup.cron}") String cleanupCron) {
return createTrigger(jobDetail, Duration.parse(cleanupCron).toMillis());
}

@Bean("tmsAttachmentCleanupJobBean")
public JobDetailFactoryBean tmsAttachmentCleanupJob() {
return createJobDetail(TmsAttachmentCleanupJob.class);
}

public SimpleTriggerFactoryBean createTriggerDelayed(JobDetail jobDetail, long pollFrequencyMs) {
SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
factoryBean.setJobDetail(jobDetail);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
* Add new handlers by implementing {@link ServerSettingHandler} and annotating with {@code @Service}
*
* @author <a href="mailto:[email protected]">Pavel Bortnik</a>
* @Component}.
*/
@Component
public class ServerSettingsRegistry {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package com.epam.ta.reportportal.core.tms.controller;

import com.epam.ta.reportportal.commons.EntityUtils;
import com.epam.ta.reportportal.commons.ReportPortalUser;
import com.epam.ta.reportportal.core.tms.dto.ProductVersionRQ;
import com.epam.ta.reportportal.core.tms.dto.TmsProductVersionRS;
import com.epam.ta.reportportal.core.tms.service.ProductVersionService;
import com.epam.ta.reportportal.util.ProjectExtractor;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* Controller for managing product versions within a project. Each endpoint
* in this controller is secured and requires the user to have administrator
* privileges. Operations supported include creating, retrieving, updating,
* and deleting product versions associated with a specific project.
*/
@RestController
@RequestMapping("/v1/project/{projectKey}/tms/productversion")
@Tag(name = "Product Version", description = "Product Version API collection")
@RequiredArgsConstructor
public class ProductVersionController {

private final ProductVersionService productVersionService;
private final ProjectExtractor projectExtractor;

/**
* Retrieves a specific product version by its ID within a project.
*
* @param projectKey The key of the project to which the product version belongs.
* @param productVersionId The ID of the product version to retrieve.
* @return A data transfer object ({@link TmsProductVersionRS}) containing details of the product version.
*/
@GetMapping("/{productVersionId}")
TmsProductVersionRS getById(@PathVariable("projectKey") String projectKey,
@PathVariable("productVersionId") final long productVersionId,
@AuthenticationPrincipal ReportPortalUser user) {
return productVersionService.getById(
projectExtractor
.extractMembershipDetails(user, EntityUtils.normalizeId(projectKey))
.getProjectId(),
productVersionId);
}

/**
* Creates a new product version in the specified project.
*
* @param projectKey The key of the project to which the new product version will be added.
* @param inputDto A request payload ({@link ProductVersionRQ}) containing information
* about the product version to create.
* @return A data transfer object ({@link TmsProductVersionRS}) with details of the created product version.
*/
@PostMapping
TmsProductVersionRS createVersion(@PathVariable("projectKey") String projectKey,
@RequestBody final ProductVersionRQ inputDto,
@AuthenticationPrincipal ReportPortalUser user) {
return productVersionService.create(
projectExtractor
.extractMembershipDetails(user, EntityUtils.normalizeId(projectKey))
.getProjectId(),
inputDto);
}

/**
* Updates the details of an existing product version in a project.
*
* @param projectKey The key of the project to which the product version belongs.
* @param productVersionId The ID of the product version to update.
* @param inputDto A request payload ({@link ProductVersionRQ}) containing updated information
* for the product version.
* @return A data transfer object ({@link TmsProductVersionRS}) with updated details of the product version.
*/
@PutMapping("/{productVersionId}")
TmsProductVersionRS updateVersion(@PathVariable("projectKey") String projectKey,
@PathVariable("productVersionId") final long productVersionId,
@RequestBody final ProductVersionRQ inputDto,
@AuthenticationPrincipal ReportPortalUser user) {
return productVersionService.update(
projectExtractor
.extractMembershipDetails(user, EntityUtils.normalizeId(projectKey))
.getProjectId(),
productVersionId,
inputDto);
}

/**
* Deletes a specific product version from a project.
*
* @param projectKey The key of the project to which the product version belongs.
* @param productVersionId The ID of the product version to delete.
*/
@DeleteMapping("/{productVersionId}")
void deleteVersion(@PathVariable("projectKey") String projectKey,
@PathVariable("productVersionId") final long productVersionId,
@AuthenticationPrincipal ReportPortalUser user) {
productVersionService.delete(
projectExtractor
.extractMembershipDetails(user, EntityUtils.normalizeId(projectKey))
.getProjectId(),
productVersionId);
}
}
Loading