From 6dc7bffe1dd4a5f1099027fa039f9298839adcd6 Mon Sep 17 00:00:00 2001 From: PHAM HOANG HUNG Date: Thu, 29 Aug 2024 16:46:25 +0700 Subject: [PATCH 01/17] MARP-612 Storing number of downloads version --- .../market/constants/EntityConstants.java | 1 + .../market/constants/MongoDBConstants.java | 3 ++ .../constants/RequestMappingConstants.java | 1 + .../controller/ProductDetailsController.java | 10 +++++ .../entity/ProductDesignerInstallation.java | 42 +++++++++++++++++++ .../repository/CustomProductRepository.java | 2 + .../impl/CustomProductRepositoryImpl.java | 15 +++++++ .../impl/ProductSearchRepositoryImpl.java | 1 - .../market/service/ProductService.java | 2 + .../service/impl/ProductServiceImpl.java | 5 +++ ...product-detail-version-action.component.ts | 22 +++++++--- .../app/modules/product/product.service.ts | 9 ++++ 12 files changed, 106 insertions(+), 7 deletions(-) create mode 100644 marketplace-service/src/main/java/com/axonivy/market/entity/ProductDesignerInstallation.java diff --git a/marketplace-service/src/main/java/com/axonivy/market/constants/EntityConstants.java b/marketplace-service/src/main/java/com/axonivy/market/constants/EntityConstants.java index edbf9ac4a..65d740596 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/constants/EntityConstants.java +++ b/marketplace-service/src/main/java/com/axonivy/market/constants/EntityConstants.java @@ -7,6 +7,7 @@ public class EntityConstants { public static final String USER = "User"; public static final String PRODUCT = "Product"; + public static final String PRODUCT_DESIGNER_INSTALLATION = "ProductDesignerInstallation"; public static final String MAVEN_ARTIFACT_VERSION = "MavenArtifactVersion"; public static final String GH_REPO_META = "GitHubRepoMeta"; public static final String FEEDBACK = "Feedback"; diff --git a/marketplace-service/src/main/java/com/axonivy/market/constants/MongoDBConstants.java b/marketplace-service/src/main/java/com/axonivy/market/constants/MongoDBConstants.java index 2915af56a..0822885ef 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/constants/MongoDBConstants.java +++ b/marketplace-service/src/main/java/com/axonivy/market/constants/MongoDBConstants.java @@ -17,4 +17,7 @@ private MongoDBConstants() { public static final String PRODUCT_MODULE_CONTENT_TAG ="$$productModuleContent.tag"; public static final String PRODUCT_COLLECTION ="Product"; public static final String NEWEST_RELEASED_VERSION_QUERY = "$newestReleaseVersion"; + public static final String PRODUCT_ID = "productId"; + public static final String DESIGNER_VERSION = "designerVersion"; + public static final String INSTALLATION_COUNT = "installationCount"; } diff --git a/marketplace-service/src/main/java/com/axonivy/market/constants/RequestMappingConstants.java b/marketplace-service/src/main/java/com/axonivy/market/constants/RequestMappingConstants.java index 6890a6424..98449f834 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/constants/RequestMappingConstants.java +++ b/marketplace-service/src/main/java/com/axonivy/market/constants/RequestMappingConstants.java @@ -23,5 +23,6 @@ public class RequestMappingConstants { public static final String INSTALLATION_COUNT_BY_ID = "/installationcount/{id}"; public static final String PRODUCT_JSON_CONTENT_BY_PRODUCT_ID_AND_VERSION = "/productjsoncontent/{productId}/{version}"; public static final String VERSIONS_IN_DESIGNER = "/{id}/designerversions"; + public static final String INSTALLATION_COUNT_BY_ID_AND_DESIGNER_VERSION = "/installationcount/{productId}/designer/{designerVersion}"; public static final String CUSTOM_SORT = "custom-sort"; } \ No newline at end of file diff --git a/marketplace-service/src/main/java/com/axonivy/market/controller/ProductDetailsController.java b/marketplace-service/src/main/java/com/axonivy/market/controller/ProductDetailsController.java index b4f396524..6a4f74dbe 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/controller/ProductDetailsController.java +++ b/marketplace-service/src/main/java/com/axonivy/market/controller/ProductDetailsController.java @@ -1,5 +1,6 @@ package com.axonivy.market.controller; +import static com.axonivy.market.constants.RequestMappingConstants.INSTALLATION_COUNT_BY_ID_AND_DESIGNER_VERSION; import static com.axonivy.market.constants.RequestMappingConstants.PRODUCT_JSON_CONTENT_BY_PRODUCT_ID_AND_VERSION; import static com.axonivy.market.constants.RequestMappingConstants.VERSIONS_IN_DESIGNER; import static com.axonivy.market.constants.RequestParamConstants.DESIGNER_VERSION; @@ -78,6 +79,15 @@ public ResponseEntity syncInstallationCount( return new ResponseEntity<>(result, HttpStatus.OK); } + @PutMapping(INSTALLATION_COUNT_BY_ID_AND_DESIGNER_VERSION) + @Operation(summary = "increase designer installation count by 1", description = "update designer installation count when click download product files by users") + public ResponseEntity increaseDesignerInstallationCount( + @PathVariable(PRODUCT_ID) @Parameter(description = "Product id (from meta.json)", example = "approval-decision-utils", in = ParameterIn.PATH) String productId, + @PathVariable(DESIGNER_VERSION) @Parameter(description = "Designer version", example = "11.4.0", in = ParameterIn.PATH) String designerVersion) { + boolean result = productService.increaseInstallationCountForProductByDesignerVersion(productId, designerVersion); + return new ResponseEntity<>(result, HttpStatus.OK); + } + @GetMapping(BY_ID) @Operation(summary = "increase installation count by 1", description = "update installation count when click download product files by users") public ResponseEntity findProductDetails( diff --git a/marketplace-service/src/main/java/com/axonivy/market/entity/ProductDesignerInstallation.java b/marketplace-service/src/main/java/com/axonivy/market/entity/ProductDesignerInstallation.java new file mode 100644 index 000000000..7c913c67d --- /dev/null +++ b/marketplace-service/src/main/java/com/axonivy/market/entity/ProductDesignerInstallation.java @@ -0,0 +1,42 @@ +package com.axonivy.market.entity; + +import lombok.*; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + +import static com.axonivy.market.constants.EntityConstants.PRODUCT_DESIGNER_INSTALLATION; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +@Builder +@Document(PRODUCT_DESIGNER_INSTALLATION) +public class ProductDesignerInstallation implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + @Id + private String id; + private String productId; + private String designerVersion; + private int installationCount; + + @Override + public int hashCode() { + return new HashCodeBuilder().append(productId).hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == null || this.getClass() != obj.getClass()) { + return false; + } + return new EqualsBuilder().append(productId, ((ProductDesignerInstallation) obj).getProductId()).isEquals(); + } +} diff --git a/marketplace-service/src/main/java/com/axonivy/market/repository/CustomProductRepository.java b/marketplace-service/src/main/java/com/axonivy/market/repository/CustomProductRepository.java index 3cd980656..75da1b126 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/repository/CustomProductRepository.java +++ b/marketplace-service/src/main/java/com/axonivy/market/repository/CustomProductRepository.java @@ -14,4 +14,6 @@ public interface CustomProductRepository { int updateInitialCount(String productId, int initialCount); int increaseInstallationCount(String productId); + + boolean increaseInstallationCountForProductByDesignerVersion(String productId, String designerVersion); } diff --git a/marketplace-service/src/main/java/com/axonivy/market/repository/impl/CustomProductRepositoryImpl.java b/marketplace-service/src/main/java/com/axonivy/market/repository/impl/CustomProductRepositoryImpl.java index c43502185..1bb232806 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/repository/impl/CustomProductRepositoryImpl.java +++ b/marketplace-service/src/main/java/com/axonivy/market/repository/impl/CustomProductRepositoryImpl.java @@ -2,7 +2,9 @@ import com.axonivy.market.constants.MongoDBConstants; import com.axonivy.market.entity.Product; +import com.axonivy.market.entity.ProductDesignerInstallation; import com.axonivy.market.repository.CustomProductRepository; +import com.mongodb.client.result.UpdateResult; import org.bson.Document; import org.springframework.data.mongodb.core.FindAndModifyOptions; import org.springframework.data.mongodb.core.MongoTemplate; @@ -99,4 +101,17 @@ public int increaseInstallationCount(String productId) { private Query createQueryById(String id) { return new Query(Criteria.where(MongoDBConstants.ID).is(id)); } + + @Override + public boolean increaseInstallationCountForProductByDesignerVersion(String productId, String designerVersion) { + Update update = new Update().inc(MongoDBConstants.INSTALLATION_COUNT, 1); + UpdateResult result = mongoTemplate.upsert(createQueryByProductIdAndDesignerVersion(productId, designerVersion), + update, ProductDesignerInstallation.class); + return result.getModifiedCount() > 0; + } + + private Query createQueryByProductIdAndDesignerVersion(String productId, String designerVersion) { + return new Query(Criteria.where(MongoDBConstants.PRODUCT_ID).is(productId) + .andOperator(Criteria.where(MongoDBConstants.DESIGNER_VERSION).is(designerVersion))); + } } diff --git a/marketplace-service/src/main/java/com/axonivy/market/repository/impl/ProductSearchRepositoryImpl.java b/marketplace-service/src/main/java/com/axonivy/market/repository/impl/ProductSearchRepositoryImpl.java index 538f8f447..68a86856f 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/repository/impl/ProductSearchRepositoryImpl.java +++ b/marketplace-service/src/main/java/com/axonivy/market/repository/impl/ProductSearchRepositoryImpl.java @@ -34,7 +34,6 @@ public ProductSearchRepositoryImpl(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; } - @Override public Page searchByCriteria(ProductSearchCriteria searchCriteria, Pageable pageable) { return getResultAsPageable(pageable, buildCriteriaSearch(searchCriteria)); diff --git a/marketplace-service/src/main/java/com/axonivy/market/service/ProductService.java b/marketplace-service/src/main/java/com/axonivy/market/service/ProductService.java index f63495616..828cd90f7 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/service/ProductService.java +++ b/marketplace-service/src/main/java/com/axonivy/market/service/ProductService.java @@ -13,6 +13,8 @@ public interface ProductService { int updateInstallationCountForProduct(String key); + boolean increaseInstallationCountForProductByDesignerVersion(String productId, String designerVersion); + Product fetchProductDetail(String id); String getCompatibilityFromOldestTag(String oldestTag); diff --git a/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductServiceImpl.java b/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductServiceImpl.java index 6c57569ae..52040bcae 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductServiceImpl.java +++ b/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductServiceImpl.java @@ -411,6 +411,11 @@ private List getProductReleaseTags(Product product) { return tags; } + @Override + public boolean increaseInstallationCountForProductByDesignerVersion(String productId, String designerVersion) { + return productRepository.increaseInstallationCountForProductByDesignerVersion(productId, designerVersion); + } + // Cover 3 cases after removing non-numeric characters (8, 11.1 and 10.0.2) @Override public String getCompatibilityFromOldestTag(String oldestTag) { diff --git a/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.ts b/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.ts index 176ef34be..b470670e3 100644 --- a/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.ts +++ b/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.ts @@ -38,7 +38,7 @@ export class ProductDetailVersionActionComponent implements AfterViewInit { @Input() product!: ProductDetail; selectedVersion = model(''); versions: WritableSignal = signal([]); - versionDropdown : Signal = computed(() => { + versionDropdown: Signal = computed(() => { return this.versions().map(version => ({ value: version, label: version @@ -52,7 +52,7 @@ export class ProductDetailVersionActionComponent implements AfterViewInit { isInvalidInstallationEnvironment = signal(false); designerVersion = ''; selectedArtifact: string | undefined = ''; - selectedArtifactName:string | undefined = ''; + selectedArtifactName: string | undefined = ''; versionMap: Map = new Map(); routingQueryParamService = inject(RoutingQueryParamService); @@ -72,7 +72,6 @@ export class ProductDetailVersionActionComponent implements AfterViewInit { this.isDesignerEnvironment.set( this.routingQueryParamService.isDesignerEnv() ); - } getInstallationTooltipText() { @@ -83,11 +82,11 @@ export class ProductDetailVersionActionComponent implements AfterViewInit { (minimum version 9.2.0)

`; } - onSelectVersion(version : string) { + onSelectVersion(version: string) { this.selectedVersion.set(version); this.artifacts.set(this.versionMap.get(this.selectedVersion()) ?? []); this.artifacts().forEach(artifact => { - if(artifact.name) { + if (artifact.name) { artifact.label = artifact.name; } }); @@ -145,7 +144,6 @@ export class ProductDetailVersionActionComponent implements AfterViewInit { }); } - getVersionInDesigner(): void { if (this.versions().length === 0) { this.productService.sendRequestToGetProductVersionsForDesigner(this.productId @@ -181,7 +179,19 @@ export class ProductDetailVersionActionComponent implements AfterViewInit { onUpdateInstallationCountForDesigner() { if (this.isDesignerEnvironment()) { this.onUpdateInstallationCount(); + this.updateInstallationCountByDesignerVersion( + this.routingQueryParamService.getDesignerVersionFromCookie(), + this.productId + ); } } + updateInstallationCountByDesignerVersion( + designerVersion: string, + productId: string + ) { + this.productService + .sendRequestToUpdateInstallationCountByDesignerVersion(designerVersion, productId) + .subscribe(); + } } diff --git a/marketplace-ui/src/app/modules/product/product.service.ts b/marketplace-ui/src/app/modules/product/product.service.ts index e708fe956..90f438c07 100644 --- a/marketplace-ui/src/app/modules/product/product.service.ts +++ b/marketplace-ui/src/app/modules/product/product.service.ts @@ -85,4 +85,13 @@ export class ProductService { return this.httpClient.get(url, { headers: { 'X-Requested-By': 'ivy' } }); } + sendRequestToUpdateInstallationCountByDesignerVersion( + designerVersion: string, + productId: string + ) { + const url = `api/product-details/installationcount/${productId}/designer/${designerVersion}`; + return this.httpClient.put(url, { + headers: { 'X-Requested-By': 'ivy' } + }); + } } From fdd4875d6ece43ff5c2ddf30f1c2becbd829640a Mon Sep 17 00:00:00 2001 From: PHAM HOANG HUNG Date: Fri, 30 Aug 2024 16:03:43 +0700 Subject: [PATCH 02/17] MARP-612 Storing number of downloads version --- .../constants/RequestMappingConstants.java | 3 +- .../controller/ProductDetailsController.java | 28 ++++++++++++---- .../market/model/DesignerInstallation.java | 24 ++++++++++++++ ...ProductDesignerInstallationRepository.java | 16 +++++++++ .../ProductDesignerInstallationService.java | 15 +++++++++ ...roductDesignerInstallationServiceImpl.java | 33 +++++++++++++++++++ .../ProductDetailsControllerTest.java | 26 +++++++++++++++ .../impl/CustomProductRepositoryImplTest.java | 17 ++++++++++ ...ct-detail-version-action.component.spec.ts | 29 ++++++++++++++-- .../modules/product/product.service.spec.ts | 14 ++++++++ .../app/modules/product/product.service.ts | 4 +-- 11 files changed, 198 insertions(+), 11 deletions(-) create mode 100644 marketplace-service/src/main/java/com/axonivy/market/model/DesignerInstallation.java create mode 100644 marketplace-service/src/main/java/com/axonivy/market/repository/ProductDesignerInstallationRepository.java create mode 100644 marketplace-service/src/main/java/com/axonivy/market/service/ProductDesignerInstallationService.java create mode 100644 marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductDesignerInstallationServiceImpl.java diff --git a/marketplace-service/src/main/java/com/axonivy/market/constants/RequestMappingConstants.java b/marketplace-service/src/main/java/com/axonivy/market/constants/RequestMappingConstants.java index 98449f834..1b145b92c 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/constants/RequestMappingConstants.java +++ b/marketplace-service/src/main/java/com/axonivy/market/constants/RequestMappingConstants.java @@ -23,6 +23,7 @@ public class RequestMappingConstants { public static final String INSTALLATION_COUNT_BY_ID = "/installationcount/{id}"; public static final String PRODUCT_JSON_CONTENT_BY_PRODUCT_ID_AND_VERSION = "/productjsoncontent/{productId}/{version}"; public static final String VERSIONS_IN_DESIGNER = "/{id}/designerversions"; - public static final String INSTALLATION_COUNT_BY_ID_AND_DESIGNER_VERSION = "/installationcount/{productId}/designer/{designerVersion}"; + public static final String DESIGNER_INSTALLATION_BY_PRODUCT_ID_AND_DESIGNER_VERSION = "/installation/{productId}/designer/{designerVersion}"; + public static final String DESIGNER_INSTALLATION_BY_PRODUCT_ID = "/installation/{productId}/designer"; public static final String CUSTOM_SORT = "custom-sort"; } \ No newline at end of file diff --git a/marketplace-service/src/main/java/com/axonivy/market/controller/ProductDetailsController.java b/marketplace-service/src/main/java/com/axonivy/market/controller/ProductDetailsController.java index 6a4f74dbe..f42b00d6d 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/controller/ProductDetailsController.java +++ b/marketplace-service/src/main/java/com/axonivy/market/controller/ProductDetailsController.java @@ -1,21 +1,25 @@ package com.axonivy.market.controller; -import static com.axonivy.market.constants.RequestMappingConstants.INSTALLATION_COUNT_BY_ID_AND_DESIGNER_VERSION; -import static com.axonivy.market.constants.RequestMappingConstants.PRODUCT_JSON_CONTENT_BY_PRODUCT_ID_AND_VERSION; -import static com.axonivy.market.constants.RequestMappingConstants.VERSIONS_IN_DESIGNER; import static com.axonivy.market.constants.RequestParamConstants.DESIGNER_VERSION; import static com.axonivy.market.constants.RequestParamConstants.ID; import static com.axonivy.market.constants.RequestParamConstants.PRODUCT_ID; import static com.axonivy.market.constants.RequestParamConstants.SHOW_DEV_VERSION; import static com.axonivy.market.constants.RequestParamConstants.VERSION; +import static com.axonivy.market.constants.RequestMappingConstants.BEST_MATCH_BY_ID_AND_VERSION; import static com.axonivy.market.constants.RequestMappingConstants.BY_ID; import static com.axonivy.market.constants.RequestMappingConstants.BY_ID_AND_VERSION; +import static com.axonivy.market.constants.RequestMappingConstants.DESIGNER_INSTALLATION_BY_PRODUCT_ID; +import static com.axonivy.market.constants.RequestMappingConstants.DESIGNER_INSTALLATION_BY_PRODUCT_ID_AND_DESIGNER_VERSION; import static com.axonivy.market.constants.RequestMappingConstants.INSTALLATION_COUNT_BY_ID; import static com.axonivy.market.constants.RequestMappingConstants.PRODUCT_DETAILS; +import static com.axonivy.market.constants.RequestMappingConstants.PRODUCT_JSON_CONTENT_BY_PRODUCT_ID_AND_VERSION; import static com.axonivy.market.constants.RequestMappingConstants.VERSIONS_BY_ID; -import static com.axonivy.market.constants.RequestMappingConstants.BEST_MATCH_BY_ID_AND_VERSION; +import static com.axonivy.market.constants.RequestMappingConstants.VERSIONS_IN_DESIGNER; import java.util.List; import java.util.Map; + +import com.axonivy.market.model.DesignerInstallation; +import com.axonivy.market.service.ProductDesignerInstallationService; import com.fasterxml.jackson.core.JsonProcessingException; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.enums.ParameterIn; @@ -44,11 +48,15 @@ public class ProductDetailsController { private final VersionService versionService; private final ProductService productService; + private final ProductDesignerInstallationService productDesignerInstallationService; private final ProductDetailModelAssembler detailModelAssembler; - public ProductDetailsController(VersionService versionService, ProductService productService, ProductDetailModelAssembler detailModelAssembler) { + public ProductDetailsController(VersionService versionService, ProductService productService, + ProductDesignerInstallationService productDesignerInstallationService, + ProductDetailModelAssembler detailModelAssembler) { this.versionService = versionService; this.productService = productService; + this.productDesignerInstallationService = productDesignerInstallationService; this.detailModelAssembler = detailModelAssembler; } @@ -79,7 +87,7 @@ public ResponseEntity syncInstallationCount( return new ResponseEntity<>(result, HttpStatus.OK); } - @PutMapping(INSTALLATION_COUNT_BY_ID_AND_DESIGNER_VERSION) + @PutMapping(DESIGNER_INSTALLATION_BY_PRODUCT_ID_AND_DESIGNER_VERSION) @Operation(summary = "increase designer installation count by 1", description = "update designer installation count when click download product files by users") public ResponseEntity increaseDesignerInstallationCount( @PathVariable(PRODUCT_ID) @Parameter(description = "Product id (from meta.json)", example = "approval-decision-utils", in = ParameterIn.PATH) String productId, @@ -88,6 +96,14 @@ public ResponseEntity increaseDesignerInstallationCount( return new ResponseEntity<>(result, HttpStatus.OK); } + @GetMapping(DESIGNER_INSTALLATION_BY_PRODUCT_ID) + @Operation(summary = "Get designer installation count by product id.", description = "get designer installation count by product id") + public ResponseEntity> getProductDesignerInstallationByProductId( + @PathVariable(PRODUCT_ID) @Parameter(description = "Product id (from meta.json)", example = "adobe-acrobat-connector", in = ParameterIn.PATH) String productId) { + List models = productDesignerInstallationService.findByProductId(productId); + return new ResponseEntity<>(models, HttpStatus.OK); + } + @GetMapping(BY_ID) @Operation(summary = "increase installation count by 1", description = "update installation count when click download product files by users") public ResponseEntity findProductDetails( diff --git a/marketplace-service/src/main/java/com/axonivy/market/model/DesignerInstallation.java b/marketplace-service/src/main/java/com/axonivy/market/model/DesignerInstallation.java new file mode 100644 index 000000000..bda1b4812 --- /dev/null +++ b/marketplace-service/src/main/java/com/axonivy/market/model/DesignerInstallation.java @@ -0,0 +1,24 @@ +package com.axonivy.market.model; + +import com.axonivy.market.entity.MavenArtifactModel; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; + +import java.util.List; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class DesignerInstallation { + @Schema(description = "Ivy designer version", example = "11.4.0") + private String designerVersion; + private int numberOfDownloads; +} diff --git a/marketplace-service/src/main/java/com/axonivy/market/repository/ProductDesignerInstallationRepository.java b/marketplace-service/src/main/java/com/axonivy/market/repository/ProductDesignerInstallationRepository.java new file mode 100644 index 000000000..b880354b8 --- /dev/null +++ b/marketplace-service/src/main/java/com/axonivy/market/repository/ProductDesignerInstallationRepository.java @@ -0,0 +1,16 @@ +package com.axonivy.market.repository; + +import com.axonivy.market.entity.Feedback; +import com.axonivy.market.entity.Product; +import com.axonivy.market.entity.ProductDesignerInstallation; +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface ProductDesignerInstallationRepository extends MongoRepository, + CustomProductRepository { + + List findByProductId(String productId); +} diff --git a/marketplace-service/src/main/java/com/axonivy/market/service/ProductDesignerInstallationService.java b/marketplace-service/src/main/java/com/axonivy/market/service/ProductDesignerInstallationService.java new file mode 100644 index 000000000..313b6ecc4 --- /dev/null +++ b/marketplace-service/src/main/java/com/axonivy/market/service/ProductDesignerInstallationService.java @@ -0,0 +1,15 @@ +package com.axonivy.market.service; + +import com.axonivy.market.entity.Product; +import com.axonivy.market.entity.ProductDesignerInstallation; +import com.axonivy.market.exceptions.model.InvalidParamException; +import com.axonivy.market.model.DesignerInstallation; +import com.axonivy.market.model.ProductCustomSortRequest; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import java.util.List; + +public interface ProductDesignerInstallationService { + List findByProductId(String productId); +} diff --git a/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductDesignerInstallationServiceImpl.java b/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductDesignerInstallationServiceImpl.java new file mode 100644 index 000000000..7f7b63c97 --- /dev/null +++ b/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductDesignerInstallationServiceImpl.java @@ -0,0 +1,33 @@ +package com.axonivy.market.service.impl; + +import com.axonivy.market.entity.ProductDesignerInstallation; +import com.axonivy.market.model.DesignerInstallation; +import com.axonivy.market.repository.ProductDesignerInstallationRepository; +import com.axonivy.market.service.ProductDesignerInstallationService; +import lombok.extern.log4j.Log4j2; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Log4j2 +@Service +public class ProductDesignerInstallationServiceImpl implements ProductDesignerInstallationService { + + private final ProductDesignerInstallationRepository productDesignerInstallationRepository; + + public ProductDesignerInstallationServiceImpl(ProductDesignerInstallationRepository productDesignerInstallationRepository) { + this.productDesignerInstallationRepository = productDesignerInstallationRepository; + } + + @Override + public List findByProductId(String productId) { + List designerInstallations = new ArrayList<>(); + List productDesignerInstallations = productDesignerInstallationRepository.findByProductId(productId); + for(ProductDesignerInstallation productDesignerInstallation: productDesignerInstallations) { + DesignerInstallation designerInstallation = new DesignerInstallation(productDesignerInstallation.getDesignerVersion(), productDesignerInstallation.getInstallationCount()); + designerInstallations.add(designerInstallation); + } + return designerInstallations; + } +} diff --git a/marketplace-service/src/test/java/com/axonivy/market/controller/ProductDetailsControllerTest.java b/marketplace-service/src/test/java/com/axonivy/market/controller/ProductDetailsControllerTest.java index 6ad422ecd..8065d61a5 100644 --- a/marketplace-service/src/test/java/com/axonivy/market/controller/ProductDetailsControllerTest.java +++ b/marketplace-service/src/test/java/com/axonivy/market/controller/ProductDetailsControllerTest.java @@ -13,6 +13,8 @@ import java.util.Map; import com.axonivy.market.constants.RequestMappingConstants; import com.axonivy.market.entity.productjsonfilecontent.ProductJsonContent; +import com.axonivy.market.model.DesignerInstallation; +import com.axonivy.market.service.ProductDesignerInstallationService; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -40,6 +42,9 @@ class ProductDetailsControllerTest { @Mock VersionService versionService; + @Mock + ProductDesignerInstallationService productDesignerInstallationService; + @Mock private ProductDetailModelAssembler detailModelAssembler; @@ -210,4 +215,25 @@ private ProductJsonContent mockProductJsonContent() { return jsonContent; } + + @Test + void testIncreaseDesignerInstallationCount() { + Mockito.when(productService.increaseInstallationCountForProductByDesignerVersion(Mockito.anyString(), + Mockito.anyString())).thenReturn(Boolean.TRUE); + ResponseEntity result = productDetailsController.increaseDesignerInstallationCount("portal", "11.4.0"); + Assertions.assertEquals(HttpStatus.OK, result.getStatusCode()); + Assertions.assertEquals(Boolean.TRUE, result.getBody()); + } + + @Test + void testGetProductDesignerInstallationByProductId() { + List models = List.of(new DesignerInstallation("11.4.0", 5)); + Mockito.when(productDesignerInstallationService.findByProductId(Mockito.anyString())).thenReturn(models); + ResponseEntity> result = productDetailsController.getProductDesignerInstallationByProductId("portal"); + Assertions.assertEquals(HttpStatus.OK, result.getStatusCode()); + Assertions.assertEquals(1, Objects.requireNonNull(result.getBody()).size()); + Assertions.assertEquals("11.4.0", result.getBody().get(0).getDesignerVersion()); + Assertions.assertEquals(5, result.getBody().get(0).getNumberOfDownloads()); + Assertions.assertEquals(models, result.getBody()); + } } diff --git a/marketplace-service/src/test/java/com/axonivy/market/repository/impl/CustomProductRepositoryImplTest.java b/marketplace-service/src/test/java/com/axonivy/market/repository/impl/CustomProductRepositoryImplTest.java index 671690f41..510168b0c 100644 --- a/marketplace-service/src/test/java/com/axonivy/market/repository/impl/CustomProductRepositoryImplTest.java +++ b/marketplace-service/src/test/java/com/axonivy/market/repository/impl/CustomProductRepositoryImplTest.java @@ -3,6 +3,8 @@ import com.axonivy.market.BaseSetup; import com.axonivy.market.constants.MongoDBConstants; import com.axonivy.market.entity.Product; +import com.axonivy.market.entity.ProductDesignerInstallation; +import com.mongodb.client.result.UpdateResult; import org.bson.Document; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -22,6 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -142,4 +145,18 @@ void testUpdateInitialCount() { repo.updateInitialCount(ID, initialCount); verify(mongoTemplate).updateFirst(any(Query.class), eq(new Update().inc("InstallationCount", initialCount).set("SynchronizedInstallationCount", true)), eq(Product.class)); } + + @Test + void testIncreaseInstallationCountForProductByDesignerVersion() { + String productId = "portal"; + String designerVersion = "11.4.0"; + ProductDesignerInstallation productDesignerInstallation = new ProductDesignerInstallation(); + productDesignerInstallation.setProductId(productId); + productDesignerInstallation.setDesignerVersion(designerVersion); + productDesignerInstallation.setInstallationCount(5); + when(mongoTemplate.upsert(any(Query.class), any(Update.class), eq(ProductDesignerInstallation.class))). + thenReturn(UpdateResult.acknowledged(1L, 1L, null)); + boolean success = repo.increaseInstallationCountForProductByDesignerVersion(productId, designerVersion); + assertTrue(success); + } } diff --git a/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.spec.ts b/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.spec.ts index c96440d10..12092bea7 100644 --- a/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.spec.ts +++ b/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.spec.ts @@ -6,6 +6,8 @@ import { ProductService } from '../../product.service'; import { provideHttpClient } from '@angular/common/http'; import { ElementRef } from '@angular/core'; import { ItemDropdown } from '../../../../shared/models/item-dropdown.model'; +import { By } from '@angular/platform-browser'; +import { MOCK_PRODUCT_DETAIL_BY_VERSION } from '../../../../shared/mocks/mock-data'; class MockElementRef implements ElementRef { nativeElement = { @@ -16,11 +18,11 @@ describe('ProductVersionActionComponent', () => { let component: ProductDetailVersionActionComponent; let fixture: ComponentFixture; let productServiceMock: any; - let elementRef: MockElementRef; beforeEach(() => { productServiceMock = jasmine.createSpyObj('ProductService', [ - 'sendRequestToProductDetailVersionAPI' , 'sendRequestToUpdateInstallationCount' + 'sendRequestToProductDetailVersionAPI' , 'sendRequestToUpdateInstallationCount', + 'sendRequestToUpdateInstallationCountByDesignerVersion' ]); TestBed.configureTestingModule({ @@ -190,4 +192,27 @@ describe('ProductVersionActionComponent', () => { // Check if window.focus() was called expect(mockWindowFocus).toHaveBeenCalled(); }); + + it('should render install designer button', () => { + component.product = MOCK_PRODUCT_DETAIL_BY_VERSION; + component.isDesignerEnvironment.set(true); + fixture.detectChanges(); + const button = fixture.debugElement.query(By.css('.install-designer-button')).nativeElement; + expect(button.id).toEqual("install-button"); + expect(button.getAttribute('product-id')).toEqual("cronjob"); + + productServiceMock.sendRequestToUpdateInstallationCount.and.returnValue( + of(1) + ); + productServiceMock.sendRequestToUpdateInstallationCountByDesignerVersion.and.returnValue( + of() + ); + + // When calling the button.click(), we got a error 'install() is not define', this method is defined in the ivy designer + // So the test will fail + // Call the method in the component instead + component.onUpdateInstallationCountForDesigner(); + expect(productServiceMock.sendRequestToUpdateInstallationCount).toHaveBeenCalledWith(component.productId); + expect(productServiceMock.sendRequestToUpdateInstallationCountByDesignerVersion).toHaveBeenCalled(); + }); }); diff --git a/marketplace-ui/src/app/modules/product/product.service.spec.ts b/marketplace-ui/src/app/modules/product/product.service.spec.ts index 69acdf603..8d7dd0551 100644 --- a/marketplace-ui/src/app/modules/product/product.service.spec.ts +++ b/marketplace-ui/src/app/modules/product/product.service.spec.ts @@ -242,4 +242,18 @@ describe('ProductService', () => { expect(req.request.headers.get('X-Requested-By')).toBe('ivy'); req.flush(['10.0.2', '10.0.1', '10.0.0']); }); + + it('should call sendRequestToUpdateInstallationCountByDesignerVersion and return true', () => { + const productId = 'google-maps-connector'; + const designerVersion = '11.4.0'; + + service.sendRequestToUpdateInstallationCountByDesignerVersion(designerVersion, productId).subscribe(response => { + expect(response).toBeTruthy(); + }); + + const req = httpMock.expectOne(`api/product-details/installation/${productId}/designer/${designerVersion}`); + expect(req.request.method).toBe('PUT'); + expect(req.request.headers.get('X-Requested-By')).toBe('ivy'); + req.flush(true); + }); }); diff --git a/marketplace-ui/src/app/modules/product/product.service.ts b/marketplace-ui/src/app/modules/product/product.service.ts index 90f438c07..48af94e8f 100644 --- a/marketplace-ui/src/app/modules/product/product.service.ts +++ b/marketplace-ui/src/app/modules/product/product.service.ts @@ -89,8 +89,8 @@ export class ProductService { designerVersion: string, productId: string ) { - const url = `api/product-details/installationcount/${productId}/designer/${designerVersion}`; - return this.httpClient.put(url, { + const url = `api/product-details/installation/${productId}/designer/${designerVersion}`; + return this.httpClient.put(url, null, { headers: { 'X-Requested-By': 'ivy' } }); } From 3d4cd81bb963034d4376fc0b75062aa9317f080c Mon Sep 17 00:00:00 2001 From: PHAM HOANG HUNG Date: Fri, 30 Aug 2024 16:36:20 +0700 Subject: [PATCH 03/17] MARP-612 Storing number of downloads version - remove unused imports --- .../com/axonivy/market/model/DesignerInstallation.java | 7 ------- .../repository/ProductDesignerInstallationRepository.java | 2 -- .../market/service/ProductDesignerInstallationService.java | 6 ------ 3 files changed, 15 deletions(-) diff --git a/marketplace-service/src/main/java/com/axonivy/market/model/DesignerInstallation.java b/marketplace-service/src/main/java/com/axonivy/market/model/DesignerInstallation.java index bda1b4812..398ad26af 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/model/DesignerInstallation.java +++ b/marketplace-service/src/main/java/com/axonivy/market/model/DesignerInstallation.java @@ -1,17 +1,10 @@ package com.axonivy.market.model; -import com.axonivy.market.entity.MavenArtifactModel; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import org.apache.commons.lang3.builder.EqualsBuilder; -import org.apache.commons.lang3.builder.HashCodeBuilder; - -import java.util.List; @Getter @Setter diff --git a/marketplace-service/src/main/java/com/axonivy/market/repository/ProductDesignerInstallationRepository.java b/marketplace-service/src/main/java/com/axonivy/market/repository/ProductDesignerInstallationRepository.java index b880354b8..8ec412114 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/repository/ProductDesignerInstallationRepository.java +++ b/marketplace-service/src/main/java/com/axonivy/market/repository/ProductDesignerInstallationRepository.java @@ -1,7 +1,5 @@ package com.axonivy.market.repository; -import com.axonivy.market.entity.Feedback; -import com.axonivy.market.entity.Product; import com.axonivy.market.entity.ProductDesignerInstallation; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.stereotype.Repository; diff --git a/marketplace-service/src/main/java/com/axonivy/market/service/ProductDesignerInstallationService.java b/marketplace-service/src/main/java/com/axonivy/market/service/ProductDesignerInstallationService.java index 313b6ecc4..046a7be7f 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/service/ProductDesignerInstallationService.java +++ b/marketplace-service/src/main/java/com/axonivy/market/service/ProductDesignerInstallationService.java @@ -1,12 +1,6 @@ package com.axonivy.market.service; -import com.axonivy.market.entity.Product; -import com.axonivy.market.entity.ProductDesignerInstallation; -import com.axonivy.market.exceptions.model.InvalidParamException; import com.axonivy.market.model.DesignerInstallation; -import com.axonivy.market.model.ProductCustomSortRequest; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import java.util.List; From ee8998d328b0dcd9d7efe35adbb6ddaddeac6775 Mon Sep 17 00:00:00 2001 From: PHAM HOANG HUNG Date: Fri, 30 Aug 2024 17:14:22 +0700 Subject: [PATCH 04/17] MARP-612 Storing number of downloads version - add tests --- ...roductDesignerInstallationServiceImpl.java | 2 +- .../java/com/axonivy/market/BaseSetup.java | 18 ++++++++ ...ctDesignerInstallationServiceImplTest.java | 44 +++++++++++++++++++ .../service/impl/ProductServiceImplTest.java | 7 +++ 4 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductDesignerInstallationServiceImplTest.java diff --git a/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductDesignerInstallationServiceImpl.java b/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductDesignerInstallationServiceImpl.java index 7f7b63c97..ba214dd71 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductDesignerInstallationServiceImpl.java +++ b/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductDesignerInstallationServiceImpl.java @@ -24,7 +24,7 @@ public ProductDesignerInstallationServiceImpl(ProductDesignerInstallationReposit public List findByProductId(String productId) { List designerInstallations = new ArrayList<>(); List productDesignerInstallations = productDesignerInstallationRepository.findByProductId(productId); - for(ProductDesignerInstallation productDesignerInstallation: productDesignerInstallations) { + for (ProductDesignerInstallation productDesignerInstallation : productDesignerInstallations) { DesignerInstallation designerInstallation = new DesignerInstallation(productDesignerInstallation.getDesignerVersion(), productDesignerInstallation.getInstallationCount()); designerInstallations.add(designerInstallation); } diff --git a/marketplace-service/src/test/java/com/axonivy/market/BaseSetup.java b/marketplace-service/src/test/java/com/axonivy/market/BaseSetup.java index d53fddf43..35ca031e0 100644 --- a/marketplace-service/src/test/java/com/axonivy/market/BaseSetup.java +++ b/marketplace-service/src/test/java/com/axonivy/market/BaseSetup.java @@ -2,8 +2,10 @@ import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; +import com.axonivy.market.entity.ProductDesignerInstallation; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; @@ -41,4 +43,20 @@ protected Page createPageProductsMock() { mockProducts.add(mockProduct); return new PageImpl<>(mockProducts); } + + protected List createProductDesignerInstallationsMock() { + var mockProductDesignerInstallations = new ArrayList(); + ProductDesignerInstallation mockProductDesignerInstallation = new ProductDesignerInstallation(); + mockProductDesignerInstallation.setProductId(SAMPLE_PRODUCT_ID); + mockProductDesignerInstallation.setDesignerVersion("10.0.22"); + mockProductDesignerInstallation.setInstallationCount(50); + mockProductDesignerInstallations.add(mockProductDesignerInstallation); + + mockProductDesignerInstallation = new ProductDesignerInstallation(); + mockProductDesignerInstallation.setProductId(SAMPLE_PRODUCT_ID); + mockProductDesignerInstallation.setDesignerVersion("11.4.0"); + mockProductDesignerInstallation.setInstallationCount(30); + mockProductDesignerInstallations.add(mockProductDesignerInstallation); + return mockProductDesignerInstallations; + } } diff --git a/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductDesignerInstallationServiceImplTest.java b/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductDesignerInstallationServiceImplTest.java new file mode 100644 index 000000000..c7ffc18c7 --- /dev/null +++ b/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductDesignerInstallationServiceImplTest.java @@ -0,0 +1,44 @@ +package com.axonivy.market.service.impl; + +import com.axonivy.market.BaseSetup; +import com.axonivy.market.entity.ProductDesignerInstallation; +import com.axonivy.market.model.DesignerInstallation; +import com.axonivy.market.repository.ProductDesignerInstallationRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class ProductDesignerInstallationServiceImplTest extends BaseSetup { + private List mockResultReturn; + @Mock + private ProductDesignerInstallationRepository productDesignerInstallationRepository; + + @InjectMocks + private ProductDesignerInstallationServiceImpl productDesignerInstallationServiceImpl; + + @BeforeEach + public void setup() { + mockResultReturn = createProductDesignerInstallationsMock(); + } + + @Test + void testFindByProductId() { + when(productDesignerInstallationRepository.findByProductId(any())).thenReturn(this.mockResultReturn); + List results = productDesignerInstallationServiceImpl.findByProductId(BaseSetup.SAMPLE_PRODUCT_ID); + assertEquals(2,results.size()); + assertEquals("10.0.22", results.get(0).getDesignerVersion()); + assertEquals(50, results.get(0).getNumberOfDownloads()); + assertEquals("11.4.0", results.get(1).getDesignerVersion()); + assertEquals(30, results.get(1).getNumberOfDownloads()); + } +} diff --git a/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java b/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java index 28328b2e2..fccb44820 100644 --- a/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java +++ b/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java @@ -201,6 +201,13 @@ void testFindProductsInRESTClientOfDesigner() { assertEquals(List.of(SHORT_DESCRIPTIONS), productSearchCriteriaArgumentCaptor.getValue().getExcludeFields()); } + @Test + void testIncreaseInstallationCountForProductByDesignerVersion() { + when(productRepository.increaseInstallationCountForProductByDesignerVersion(any(), any())).thenReturn(true); + boolean success = productService.increaseInstallationCountForProductByDesignerVersion("portal", "11.4.0"); + assertTrue(success); + } + @Test void testSyncProductsAsUpdateMetaJSONFromGitHub() throws IOException { // Start testing by adding new meta From 21372984e35acf11b3654ee080ec62ad692311bb Mon Sep 17 00:00:00 2001 From: PHAM HOANG HUNG Date: Fri, 30 Aug 2024 17:45:47 +0700 Subject: [PATCH 05/17] MARP-612 Storing number of downloads version - handle sort desc --- .../repository/ProductDesignerInstallationRepository.java | 3 ++- .../impl/ProductDesignerInstallationServiceImpl.java | 6 ++++-- .../impl/ProductDesignerInstallationServiceImplTest.java | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/marketplace-service/src/main/java/com/axonivy/market/repository/ProductDesignerInstallationRepository.java b/marketplace-service/src/main/java/com/axonivy/market/repository/ProductDesignerInstallationRepository.java index 8ec412114..34b6c6dbc 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/repository/ProductDesignerInstallationRepository.java +++ b/marketplace-service/src/main/java/com/axonivy/market/repository/ProductDesignerInstallationRepository.java @@ -1,6 +1,7 @@ package com.axonivy.market.repository; import com.axonivy.market.entity.ProductDesignerInstallation; +import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.stereotype.Repository; @@ -10,5 +11,5 @@ public interface ProductDesignerInstallationRepository extends MongoRepository, CustomProductRepository { - List findByProductId(String productId); + List findByProductId(String productId, Sort sort); } diff --git a/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductDesignerInstallationServiceImpl.java b/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductDesignerInstallationServiceImpl.java index ba214dd71..c95241e08 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductDesignerInstallationServiceImpl.java +++ b/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductDesignerInstallationServiceImpl.java @@ -1,10 +1,12 @@ package com.axonivy.market.service.impl; +import com.axonivy.market.constants.MongoDBConstants; import com.axonivy.market.entity.ProductDesignerInstallation; import com.axonivy.market.model.DesignerInstallation; import com.axonivy.market.repository.ProductDesignerInstallationRepository; import com.axonivy.market.service.ProductDesignerInstallationService; import lombok.extern.log4j.Log4j2; +import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import java.util.ArrayList; @@ -13,7 +15,6 @@ @Log4j2 @Service public class ProductDesignerInstallationServiceImpl implements ProductDesignerInstallationService { - private final ProductDesignerInstallationRepository productDesignerInstallationRepository; public ProductDesignerInstallationServiceImpl(ProductDesignerInstallationRepository productDesignerInstallationRepository) { @@ -23,7 +24,8 @@ public ProductDesignerInstallationServiceImpl(ProductDesignerInstallationReposit @Override public List findByProductId(String productId) { List designerInstallations = new ArrayList<>(); - List productDesignerInstallations = productDesignerInstallationRepository.findByProductId(productId); + List productDesignerInstallations = + productDesignerInstallationRepository.findByProductId(productId, Sort.by(Sort.Direction.DESC, MongoDBConstants.DESIGNER_VERSION)); for (ProductDesignerInstallation productDesignerInstallation : productDesignerInstallations) { DesignerInstallation designerInstallation = new DesignerInstallation(productDesignerInstallation.getDesignerVersion(), productDesignerInstallation.getInstallationCount()); designerInstallations.add(designerInstallation); diff --git a/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductDesignerInstallationServiceImplTest.java b/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductDesignerInstallationServiceImplTest.java index c7ffc18c7..6e8998fef 100644 --- a/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductDesignerInstallationServiceImplTest.java +++ b/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductDesignerInstallationServiceImplTest.java @@ -33,7 +33,7 @@ public void setup() { @Test void testFindByProductId() { - when(productDesignerInstallationRepository.findByProductId(any())).thenReturn(this.mockResultReturn); + when(productDesignerInstallationRepository.findByProductId(any(), any())).thenReturn(this.mockResultReturn); List results = productDesignerInstallationServiceImpl.findByProductId(BaseSetup.SAMPLE_PRODUCT_ID); assertEquals(2,results.size()); assertEquals("10.0.22", results.get(0).getDesignerVersion()); From 21f34a683db3bce9e55fca5ee71826e687b81e87 Mon Sep 17 00:00:00 2001 From: PHAM HOANG HUNG Date: Thu, 5 Sep 2024 17:25:03 +0700 Subject: [PATCH 06/17] MARP-612 Storing number of downloads version - handle feedback --- .../repository/ProductDesignerInstallationRepository.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/marketplace-service/src/main/java/com/axonivy/market/repository/ProductDesignerInstallationRepository.java b/marketplace-service/src/main/java/com/axonivy/market/repository/ProductDesignerInstallationRepository.java index 34b6c6dbc..2b5789521 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/repository/ProductDesignerInstallationRepository.java +++ b/marketplace-service/src/main/java/com/axonivy/market/repository/ProductDesignerInstallationRepository.java @@ -8,8 +8,7 @@ import java.util.List; @Repository -public interface ProductDesignerInstallationRepository extends MongoRepository, - CustomProductRepository { +public interface ProductDesignerInstallationRepository extends MongoRepository { List findByProductId(String productId, Sort sort); } From 1faffe6fbe1ea287b1bc69110c093702c7bfc803 Mon Sep 17 00:00:00 2001 From: PHAM HOANG HUNG Date: Fri, 6 Sep 2024 11:10:01 +0700 Subject: [PATCH 07/17] MARP-612 Handle feedback --- .../constants/RequestMappingConstants.java | 1 + ...ProductDesignerInstallationController.java | 38 +++++++++++ .../controller/ProductDetailsController.java | 29 +-------- .../repository/CustomProductRepository.java | 2 +- .../impl/CustomProductRepositoryImpl.java | 5 +- .../market/service/ProductService.java | 4 +- .../service/impl/ProductServiceImpl.java | 10 ++- ...uctDesignerInstallationControllerTest.java | 39 +++++++++++ .../ProductDetailsControllerTest.java | 26 +------- .../impl/CustomProductRepositoryImplTest.java | 14 ---- .../service/impl/ProductServiceImplTest.java | 11 +--- ...ct-detail-version-action.component.spec.ts | 28 +------- ...product-detail-version-action.component.ts | 64 +++++++++++-------- .../app/modules/product/product.service.ts | 17 ++--- 14 files changed, 135 insertions(+), 153 deletions(-) create mode 100644 marketplace-service/src/main/java/com/axonivy/market/controller/ProductDesignerInstallationController.java create mode 100644 marketplace-service/src/test/java/com/axonivy/market/controller/ProductDesignerInstallationControllerTest.java diff --git a/marketplace-service/src/main/java/com/axonivy/market/constants/RequestMappingConstants.java b/marketplace-service/src/main/java/com/axonivy/market/constants/RequestMappingConstants.java index 1b145b92c..abfc30ba3 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/constants/RequestMappingConstants.java +++ b/marketplace-service/src/main/java/com/axonivy/market/constants/RequestMappingConstants.java @@ -10,6 +10,7 @@ public class RequestMappingConstants { public static final String SYNC = "sync"; public static final String PRODUCT = API + "/product"; public static final String PRODUCT_DETAILS = API + "/product-details"; + public static final String PRODUCT_DESIGNER_INSTALLATION = API + "/product-designer-installation"; public static final String FEEDBACK = API + "/feedback"; public static final String SWAGGER_URL = "/swagger-ui/index.html"; public static final String GIT_HUB_LOGIN = "/github/login"; diff --git a/marketplace-service/src/main/java/com/axonivy/market/controller/ProductDesignerInstallationController.java b/marketplace-service/src/main/java/com/axonivy/market/controller/ProductDesignerInstallationController.java new file mode 100644 index 000000000..645717df2 --- /dev/null +++ b/marketplace-service/src/main/java/com/axonivy/market/controller/ProductDesignerInstallationController.java @@ -0,0 +1,38 @@ +package com.axonivy.market.controller; + +import com.axonivy.market.model.DesignerInstallation; +import com.axonivy.market.service.ProductDesignerInstallationService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +import static com.axonivy.market.constants.RequestMappingConstants.DESIGNER_INSTALLATION_BY_PRODUCT_ID; +import static com.axonivy.market.constants.RequestMappingConstants.PRODUCT_DESIGNER_INSTALLATION; +import static com.axonivy.market.constants.RequestParamConstants.PRODUCT_ID; + +@RestController +@RequestMapping(PRODUCT_DESIGNER_INSTALLATION) +@Tag(name = "Product Designer Installation Controllers", description = "API collection to get designer installation count.") +public class ProductDesignerInstallationController { + private final ProductDesignerInstallationService productDesignerInstallationService; + + public ProductDesignerInstallationController(ProductDesignerInstallationService productDesignerInstallationService) { + this.productDesignerInstallationService = productDesignerInstallationService; + } + + @GetMapping(DESIGNER_INSTALLATION_BY_PRODUCT_ID) + @Operation(summary = "Get designer installation count by product id.", description = "get designer installation count by product id") + public ResponseEntity> getProductDesignerInstallationByProductId(@PathVariable(PRODUCT_ID) @Parameter(description = "Product id (from meta.json)", example = "adobe-acrobat-connector", in = ParameterIn.PATH) String productId) { + List models = productDesignerInstallationService.findByProductId(productId); + return new ResponseEntity<>(models, HttpStatus.OK); + } +} diff --git a/marketplace-service/src/main/java/com/axonivy/market/controller/ProductDetailsController.java b/marketplace-service/src/main/java/com/axonivy/market/controller/ProductDetailsController.java index 1cd0cf60a..9fe0b9ef6 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/controller/ProductDetailsController.java +++ b/marketplace-service/src/main/java/com/axonivy/market/controller/ProductDetailsController.java @@ -8,8 +8,6 @@ import static com.axonivy.market.constants.RequestMappingConstants.BEST_MATCH_BY_ID_AND_VERSION; import static com.axonivy.market.constants.RequestMappingConstants.BY_ID; import static com.axonivy.market.constants.RequestMappingConstants.BY_ID_AND_VERSION; -import static com.axonivy.market.constants.RequestMappingConstants.DESIGNER_INSTALLATION_BY_PRODUCT_ID; -import static com.axonivy.market.constants.RequestMappingConstants.DESIGNER_INSTALLATION_BY_PRODUCT_ID_AND_DESIGNER_VERSION; import static com.axonivy.market.constants.RequestMappingConstants.INSTALLATION_COUNT_BY_ID; import static com.axonivy.market.constants.RequestMappingConstants.PRODUCT_DETAILS; import static com.axonivy.market.constants.RequestMappingConstants.PRODUCT_JSON_CONTENT_BY_PRODUCT_ID_AND_VERSION; @@ -18,8 +16,6 @@ import java.util.List; import java.util.Map; -import com.axonivy.market.model.DesignerInstallation; -import com.axonivy.market.service.ProductDesignerInstallationService; import com.axonivy.market.model.VersionAndUrlModel; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.enums.ParameterIn; @@ -48,15 +44,12 @@ public class ProductDetailsController { private final VersionService versionService; private final ProductService productService; - private final ProductDesignerInstallationService productDesignerInstallationService; private final ProductDetailModelAssembler detailModelAssembler; public ProductDetailsController(VersionService versionService, ProductService productService, - ProductDesignerInstallationService productDesignerInstallationService, ProductDetailModelAssembler detailModelAssembler) { this.versionService = versionService; this.productService = productService; - this.productDesignerInstallationService = productDesignerInstallationService; this.detailModelAssembler = detailModelAssembler; } @@ -82,28 +75,12 @@ public ResponseEntity findBestMatchProductDetailsByVersion( @PutMapping(INSTALLATION_COUNT_BY_ID) @Operation(summary = "Update installation count of product", description = "By default, increase installation count when click download product files by users") public ResponseEntity syncInstallationCount( - @PathVariable(ID) @Parameter(description = "Product id (from meta.json)", example = "approval-decision-utils", in = ParameterIn.PATH) String productId) { - int result = productService.updateInstallationCountForProduct(productId); - return new ResponseEntity<>(result, HttpStatus.OK); - } - - @PutMapping(DESIGNER_INSTALLATION_BY_PRODUCT_ID_AND_DESIGNER_VERSION) - @Operation(summary = "increase designer installation count by 1", description = "update designer installation count when click download product files by users") - public ResponseEntity increaseDesignerInstallationCount( - @PathVariable(PRODUCT_ID) @Parameter(description = "Product id (from meta.json)", example = "approval-decision-utils", in = ParameterIn.PATH) String productId, - @PathVariable(DESIGNER_VERSION) @Parameter(description = "Designer version", example = "11.4.0", in = ParameterIn.PATH) String designerVersion) { - boolean result = productService.increaseInstallationCountForProductByDesignerVersion(productId, designerVersion); + @PathVariable(ID) @Parameter(description = "Product id (from meta.json)", example = "approval-decision-utils", in = ParameterIn.PATH) String productId, + @RequestParam(name = DESIGNER_VERSION, required = false) @Parameter(in = ParameterIn.QUERY, example = "v10.0.20") String designerVersion) { + int result = productService.updateInstallationCountForProduct(productId, designerVersion); return new ResponseEntity<>(result, HttpStatus.OK); } - @GetMapping(DESIGNER_INSTALLATION_BY_PRODUCT_ID) - @Operation(summary = "Get designer installation count by product id.", description = "get designer installation count by product id") - public ResponseEntity> getProductDesignerInstallationByProductId( - @PathVariable(PRODUCT_ID) @Parameter(description = "Product id (from meta.json)", example = "adobe-acrobat-connector", in = ParameterIn.PATH) String productId) { - List models = productDesignerInstallationService.findByProductId(productId); - return new ResponseEntity<>(models, HttpStatus.OK); - } - @GetMapping(BY_ID) @Operation(summary = "increase installation count by 1", description = "update installation count when click download product files by users") public ResponseEntity findProductDetails( diff --git a/marketplace-service/src/main/java/com/axonivy/market/repository/CustomProductRepository.java b/marketplace-service/src/main/java/com/axonivy/market/repository/CustomProductRepository.java index 75da1b126..3fc59e926 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/repository/CustomProductRepository.java +++ b/marketplace-service/src/main/java/com/axonivy/market/repository/CustomProductRepository.java @@ -15,5 +15,5 @@ public interface CustomProductRepository { int increaseInstallationCount(String productId); - boolean increaseInstallationCountForProductByDesignerVersion(String productId, String designerVersion); + void increaseInstallationCountForProductByDesignerVersion(String productId, String designerVersion); } diff --git a/marketplace-service/src/main/java/com/axonivy/market/repository/impl/CustomProductRepositoryImpl.java b/marketplace-service/src/main/java/com/axonivy/market/repository/impl/CustomProductRepositoryImpl.java index 1bb232806..72f09dad3 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/repository/impl/CustomProductRepositoryImpl.java +++ b/marketplace-service/src/main/java/com/axonivy/market/repository/impl/CustomProductRepositoryImpl.java @@ -103,11 +103,10 @@ private Query createQueryById(String id) { } @Override - public boolean increaseInstallationCountForProductByDesignerVersion(String productId, String designerVersion) { + public void increaseInstallationCountForProductByDesignerVersion(String productId, String designerVersion) { Update update = new Update().inc(MongoDBConstants.INSTALLATION_COUNT, 1); - UpdateResult result = mongoTemplate.upsert(createQueryByProductIdAndDesignerVersion(productId, designerVersion), + mongoTemplate.upsert(createQueryByProductIdAndDesignerVersion(productId, designerVersion), update, ProductDesignerInstallation.class); - return result.getModifiedCount() > 0; } private Query createQueryByProductIdAndDesignerVersion(String productId, String designerVersion) { diff --git a/marketplace-service/src/main/java/com/axonivy/market/service/ProductService.java b/marketplace-service/src/main/java/com/axonivy/market/service/ProductService.java index 828cd90f7..44c27771f 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/service/ProductService.java +++ b/marketplace-service/src/main/java/com/axonivy/market/service/ProductService.java @@ -11,9 +11,7 @@ public interface ProductService { boolean syncLatestDataFromMarketRepo(); - int updateInstallationCountForProduct(String key); - - boolean increaseInstallationCountForProductByDesignerVersion(String productId, String designerVersion); + int updateInstallationCountForProduct(String key, String designerVersion); Product fetchProductDetail(String id); diff --git a/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductServiceImpl.java b/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductServiceImpl.java index 52040bcae..a76f2ccf6 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductServiceImpl.java +++ b/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductServiceImpl.java @@ -141,7 +141,7 @@ public boolean syncLatestDataFromMarketRepo() { } @Override - public int updateInstallationCountForProduct(String key) { + public int updateInstallationCountForProduct(String key, String designerVersion) { Product product= productRepository.getProductById(key); if (Objects.isNull(product)){ return 0; @@ -151,6 +151,9 @@ public int updateInstallationCountForProduct(String key) { return productRepository.increaseInstallationCount(key); } syncInstallationCountWithProduct(product); + if (StringUtils.isNotBlank(designerVersion)) { + productRepository.increaseInstallationCountForProductByDesignerVersion(key, designerVersion); + } return productRepository.updateInitialCount(key, product.getInstallationCount() + 1); } @@ -411,11 +414,6 @@ private List getProductReleaseTags(Product product) { return tags; } - @Override - public boolean increaseInstallationCountForProductByDesignerVersion(String productId, String designerVersion) { - return productRepository.increaseInstallationCountForProductByDesignerVersion(productId, designerVersion); - } - // Cover 3 cases after removing non-numeric characters (8, 11.1 and 10.0.2) @Override public String getCompatibilityFromOldestTag(String oldestTag) { diff --git a/marketplace-service/src/test/java/com/axonivy/market/controller/ProductDesignerInstallationControllerTest.java b/marketplace-service/src/test/java/com/axonivy/market/controller/ProductDesignerInstallationControllerTest.java new file mode 100644 index 000000000..b8fd3f553 --- /dev/null +++ b/marketplace-service/src/test/java/com/axonivy/market/controller/ProductDesignerInstallationControllerTest.java @@ -0,0 +1,39 @@ +package com.axonivy.market.controller; + +import com.axonivy.market.model.DesignerInstallation; +import com.axonivy.market.service.ProductDesignerInstallationService; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import java.util.List; +import java.util.Objects; + +@ExtendWith(MockitoExtension.class) +class ProductDesignerInstallationControllerTest { + public static final String DESIGNER_VERSION = "11.4.0"; + + @Mock + ProductDesignerInstallationService productDesignerInstallationService; + + @InjectMocks + private ProductDesignerInstallationController productDesignerInstallationController; + + @Test + void testGetProductDesignerInstallationByProductId() { + List models = List.of(new DesignerInstallation(DESIGNER_VERSION, 5)); + Mockito.when(productDesignerInstallationService.findByProductId(Mockito.anyString())).thenReturn(models); + ResponseEntity> result = productDesignerInstallationController.getProductDesignerInstallationByProductId("portal"); + Assertions.assertEquals(HttpStatus.OK, result.getStatusCode()); + Assertions.assertEquals(1, Objects.requireNonNull(result.getBody()).size()); + Assertions.assertEquals(DESIGNER_VERSION, result.getBody().get(0).getDesignerVersion()); + Assertions.assertEquals(5, result.getBody().get(0).getNumberOfDownloads()); + Assertions.assertEquals(models, result.getBody()); + } +} diff --git a/marketplace-service/src/test/java/com/axonivy/market/controller/ProductDetailsControllerTest.java b/marketplace-service/src/test/java/com/axonivy/market/controller/ProductDetailsControllerTest.java index 4c015a88d..05f37b299 100644 --- a/marketplace-service/src/test/java/com/axonivy/market/controller/ProductDetailsControllerTest.java +++ b/marketplace-service/src/test/java/com/axonivy/market/controller/ProductDetailsControllerTest.java @@ -14,7 +14,6 @@ import com.axonivy.market.constants.RequestMappingConstants; import com.axonivy.market.entity.ProductJsonContent; import com.axonivy.market.model.VersionAndUrlModel; -import com.axonivy.market.model.DesignerInstallation; import com.axonivy.market.service.ProductDesignerInstallationService; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Assertions; @@ -121,9 +120,9 @@ void testFindProductVersionsById() { @Test void testSyncInstallationCount() { - when(productService.updateInstallationCountForProduct("google-maps-connector")).thenReturn(1); + when(productService.updateInstallationCountForProduct("google-maps-connector", "10.0.20")).thenReturn(1); - var result = productDetailsController.syncInstallationCount("google-maps-connector"); + var result = productDetailsController.syncInstallationCount("google-maps-connector", "10.0.20"); assertEquals(1, result.getBody()); } @@ -232,25 +231,4 @@ private ProductJsonContent mockProductJsonContent() { return jsonContent; } - - @Test - void testIncreaseDesignerInstallationCount() { - Mockito.when(productService.increaseInstallationCountForProductByDesignerVersion(Mockito.anyString(), - Mockito.anyString())).thenReturn(Boolean.TRUE); - ResponseEntity result = productDetailsController.increaseDesignerInstallationCount("portal", "11.4.0"); - Assertions.assertEquals(HttpStatus.OK, result.getStatusCode()); - Assertions.assertEquals(Boolean.TRUE, result.getBody()); - } - - @Test - void testGetProductDesignerInstallationByProductId() { - List models = List.of(new DesignerInstallation("11.4.0", 5)); - Mockito.when(productDesignerInstallationService.findByProductId(Mockito.anyString())).thenReturn(models); - ResponseEntity> result = productDetailsController.getProductDesignerInstallationByProductId("portal"); - Assertions.assertEquals(HttpStatus.OK, result.getStatusCode()); - Assertions.assertEquals(1, Objects.requireNonNull(result.getBody()).size()); - Assertions.assertEquals("11.4.0", result.getBody().get(0).getDesignerVersion()); - Assertions.assertEquals(5, result.getBody().get(0).getNumberOfDownloads()); - Assertions.assertEquals(models, result.getBody()); - } } diff --git a/marketplace-service/src/test/java/com/axonivy/market/repository/impl/CustomProductRepositoryImplTest.java b/marketplace-service/src/test/java/com/axonivy/market/repository/impl/CustomProductRepositoryImplTest.java index 510168b0c..9133d4ab9 100644 --- a/marketplace-service/src/test/java/com/axonivy/market/repository/impl/CustomProductRepositoryImplTest.java +++ b/marketplace-service/src/test/java/com/axonivy/market/repository/impl/CustomProductRepositoryImplTest.java @@ -145,18 +145,4 @@ void testUpdateInitialCount() { repo.updateInitialCount(ID, initialCount); verify(mongoTemplate).updateFirst(any(Query.class), eq(new Update().inc("InstallationCount", initialCount).set("SynchronizedInstallationCount", true)), eq(Product.class)); } - - @Test - void testIncreaseInstallationCountForProductByDesignerVersion() { - String productId = "portal"; - String designerVersion = "11.4.0"; - ProductDesignerInstallation productDesignerInstallation = new ProductDesignerInstallation(); - productDesignerInstallation.setProductId(productId); - productDesignerInstallation.setDesignerVersion(designerVersion); - productDesignerInstallation.setInstallationCount(5); - when(mongoTemplate.upsert(any(Query.class), any(Update.class), eq(ProductDesignerInstallation.class))). - thenReturn(UpdateResult.acknowledged(1L, 1L, null)); - boolean success = repo.increaseInstallationCountForProductByDesignerVersion(productId, designerVersion); - assertTrue(success); - } } diff --git a/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java b/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java index fccb44820..103c8a3a1 100644 --- a/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java +++ b/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java @@ -133,13 +133,13 @@ public void setup() { @Test void testUpdateInstallationCountForProduct() { - int result = productService.updateInstallationCountForProduct(null); + int result = productService.updateInstallationCountForProduct(null, "10.0.20"); assertEquals(0, result); Product product = mockProduct(); when(productRepository.getProductById(product.getId())).thenReturn(product); when(productRepository.increaseInstallationCount(product.getId())).thenReturn(31); - result = productService.updateInstallationCountForProduct(product.getId()); + result = productService.updateInstallationCountForProduct(product.getId(), "10.0.20"); assertEquals(31,result); } @@ -201,13 +201,6 @@ void testFindProductsInRESTClientOfDesigner() { assertEquals(List.of(SHORT_DESCRIPTIONS), productSearchCriteriaArgumentCaptor.getValue().getExcludeFields()); } - @Test - void testIncreaseInstallationCountForProductByDesignerVersion() { - when(productRepository.increaseInstallationCountForProductByDesignerVersion(any(), any())).thenReturn(true); - boolean success = productService.increaseInstallationCountForProductByDesignerVersion("portal", "11.4.0"); - assertTrue(success); - } - @Test void testSyncProductsAsUpdateMetaJSONFromGitHub() throws IOException { // Start testing by adding new meta diff --git a/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.spec.ts b/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.spec.ts index 12092bea7..825a955c0 100644 --- a/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.spec.ts +++ b/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.spec.ts @@ -6,8 +6,6 @@ import { ProductService } from '../../product.service'; import { provideHttpClient } from '@angular/common/http'; import { ElementRef } from '@angular/core'; import { ItemDropdown } from '../../../../shared/models/item-dropdown.model'; -import { By } from '@angular/platform-browser'; -import { MOCK_PRODUCT_DETAIL_BY_VERSION } from '../../../../shared/mocks/mock-data'; class MockElementRef implements ElementRef { nativeElement = { @@ -21,8 +19,7 @@ describe('ProductVersionActionComponent', () => { beforeEach(() => { productServiceMock = jasmine.createSpyObj('ProductService', [ - 'sendRequestToProductDetailVersionAPI' , 'sendRequestToUpdateInstallationCount', - 'sendRequestToUpdateInstallationCountByDesignerVersion' + 'sendRequestToProductDetailVersionAPI' , 'sendRequestToUpdateInstallationCount' ]); TestBed.configureTestingModule({ @@ -192,27 +189,4 @@ describe('ProductVersionActionComponent', () => { // Check if window.focus() was called expect(mockWindowFocus).toHaveBeenCalled(); }); - - it('should render install designer button', () => { - component.product = MOCK_PRODUCT_DETAIL_BY_VERSION; - component.isDesignerEnvironment.set(true); - fixture.detectChanges(); - const button = fixture.debugElement.query(By.css('.install-designer-button')).nativeElement; - expect(button.id).toEqual("install-button"); - expect(button.getAttribute('product-id')).toEqual("cronjob"); - - productServiceMock.sendRequestToUpdateInstallationCount.and.returnValue( - of(1) - ); - productServiceMock.sendRequestToUpdateInstallationCountByDesignerVersion.and.returnValue( - of() - ); - - // When calling the button.click(), we got a error 'install() is not define', this method is defined in the ivy designer - // So the test will fail - // Call the method in the component instead - component.onUpdateInstallationCountForDesigner(); - expect(productServiceMock.sendRequestToUpdateInstallationCount).toHaveBeenCalledWith(component.productId); - expect(productServiceMock.sendRequestToUpdateInstallationCountByDesignerVersion).toHaveBeenCalled(); - }); }); diff --git a/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.ts b/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.ts index 3657e511a..4236a2867 100644 --- a/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.ts +++ b/marketplace-ui/src/app/modules/product/product-detail/product-detail-version-action/product-detail-version-action.component.ts @@ -1,10 +1,14 @@ import { AfterViewInit, - Component, computed, - ElementRef, EventEmitter, + Component, + computed, + ElementRef, + EventEmitter, inject, Input, - model, Output, Signal, + model, + Output, + Signal, signal, WritableSignal } from '@angular/core'; @@ -27,7 +31,12 @@ const delayTimeBeforeHideMessage = 2000; @Component({ selector: 'app-product-version-action', standalone: true, - imports: [CommonModule, TranslateModule, FormsModule, CommonDropdownComponent], + imports: [ + CommonModule, + TranslateModule, + FormsModule, + CommonDropdownComponent + ], templateUrl: './product-detail-version-action.component.html', styleUrl: './product-detail-version-action.component.scss' }) @@ -42,7 +51,7 @@ export class ProductDetailVersionActionComponent implements AfterViewInit { versionDropdown: Signal = computed(() => { return this.versions().map(version => ({ value: version, - label: version, + label: version })); }); metaDataJsonUrl = model(''); @@ -149,16 +158,25 @@ export class ProductDetailVersionActionComponent implements AfterViewInit { getVersionInDesigner(): void { if (this.versions().length === 0) { - this.productService.sendRequestToGetProductVersionsForDesigner(this.productId - ).subscribe(data => { - const versionMap = data.map(dataVersionAndUrl => dataVersionAndUrl.version).map(version => VERSION.displayPrefix.concat(version)); - data.forEach(dataVersionAndUrl => { - const currentVersion = VERSION.displayPrefix.concat(dataVersionAndUrl.version); - const versionAndUrl: ItemDropdown = { value: currentVersion, label: currentVersion, metaDataJsonUrl: dataVersionAndUrl.url }; - this.versionDropdownInDesigner.push(versionAndUrl); + this.productService + .sendRequestToGetProductVersionsForDesigner(this.productId) + .subscribe(data => { + const versionMap = data + .map(dataVersionAndUrl => dataVersionAndUrl.version) + .map(version => VERSION.displayPrefix.concat(version)); + data.forEach(dataVersionAndUrl => { + const currentVersion = VERSION.displayPrefix.concat( + dataVersionAndUrl.version + ); + const versionAndUrl: ItemDropdown = { + value: currentVersion, + label: currentVersion, + metaDataJsonUrl: dataVersionAndUrl.url + }; + this.versionDropdownInDesigner.push(versionAndUrl); + }); + this.versions.set(versionMap); }); - this.versions.set(versionMap); - }); } } @@ -180,26 +198,16 @@ export class ProductDetailVersionActionComponent implements AfterViewInit { onUpdateInstallationCount() { this.productService - .sendRequestToUpdateInstallationCount(this.productId) + .sendRequestToUpdateInstallationCount( + this.productId, + this.routingQueryParamService.getDesignerVersionFromCookie() + ) .subscribe((data: number) => this.installationCount.emit(data)); } onUpdateInstallationCountForDesigner() { if (this.isDesignerEnvironment()) { this.onUpdateInstallationCount(); - this.updateInstallationCountByDesignerVersion( - this.routingQueryParamService.getDesignerVersionFromCookie(), - this.productId - ); } } - - updateInstallationCountByDesignerVersion( - designerVersion: string, - productId: string - ) { - this.productService - .sendRequestToUpdateInstallationCountByDesignerVersion(designerVersion, productId) - .subscribe(); - } } diff --git a/marketplace-ui/src/app/modules/product/product.service.ts b/marketplace-ui/src/app/modules/product/product.service.ts index 2382c6b47..9dafac5d6 100644 --- a/marketplace-ui/src/app/modules/product/product.service.ts +++ b/marketplace-ui/src/app/modules/product/product.service.ts @@ -76,23 +76,16 @@ export class ProductService { ); } - sendRequestToUpdateInstallationCount(productId: string) { + sendRequestToUpdateInstallationCount(productId: string, designerVersion: string) { const url = 'api/product-details/installationcount/' + productId; - return this.httpClient.put(url, null, { headers: { 'X-Requested-By': 'ivy' } }); + return this.httpClient.put(url, null, { + headers: { 'X-Requested-By': 'ivy' }, + params: { 'designerVersion:': designerVersion } + }); } sendRequestToGetProductVersionsForDesigner(productId: string) { const url = `api/product-details/${productId}/designerversions`; return this.httpClient.get(url, { headers: { 'X-Requested-By': 'ivy' } }); } - - sendRequestToUpdateInstallationCountByDesignerVersion( - designerVersion: string, - productId: string - ) { - const url = `api/product-details/installation/${productId}/designer/${designerVersion}`; - return this.httpClient.put(url, null, { - headers: { 'X-Requested-By': 'ivy' } - }); - } } From 92c9b2e10cf685927260c5b1c410c2911c4272a9 Mon Sep 17 00:00:00 2001 From: PHAM HOANG HUNG Date: Fri, 6 Sep 2024 11:19:27 +0700 Subject: [PATCH 08/17] fix sonar --- .../repository/impl/CustomProductRepositoryImplTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/marketplace-service/src/test/java/com/axonivy/market/repository/impl/CustomProductRepositoryImplTest.java b/marketplace-service/src/test/java/com/axonivy/market/repository/impl/CustomProductRepositoryImplTest.java index 9133d4ab9..671690f41 100644 --- a/marketplace-service/src/test/java/com/axonivy/market/repository/impl/CustomProductRepositoryImplTest.java +++ b/marketplace-service/src/test/java/com/axonivy/market/repository/impl/CustomProductRepositoryImplTest.java @@ -3,8 +3,6 @@ import com.axonivy.market.BaseSetup; import com.axonivy.market.constants.MongoDBConstants; import com.axonivy.market.entity.Product; -import com.axonivy.market.entity.ProductDesignerInstallation; -import com.mongodb.client.result.UpdateResult; import org.bson.Document; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -24,7 +22,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; From b38c577eeee38a9f5b96a79ac9acb75c756f85c7 Mon Sep 17 00:00:00 2001 From: PHAM HOANG HUNG Date: Fri, 6 Sep 2024 14:46:55 +0700 Subject: [PATCH 09/17] fix test --- .../axonivy/market/service/impl/ProductServiceImpl.java | 9 ++++++--- .../repository/impl/CustomProductRepositoryImplTest.java | 7 +++++++ .../market/service/impl/ProductServiceImplTest.java | 5 +++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductServiceImpl.java b/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductServiceImpl.java index e4d872c7d..a5c2f3e6b 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductServiceImpl.java +++ b/marketplace-service/src/main/java/com/axonivy/market/service/impl/ProductServiceImpl.java @@ -149,14 +149,17 @@ public int updateInstallationCountForProduct(String key, String designerVersion) if (Objects.isNull(product)){ return 0; } + + log.info("Increase installation count for product {} By Designer Version {}", key, designerVersion); + if (StringUtils.isNotBlank(designerVersion)) { + productRepository.increaseInstallationCountForProductByDesignerVersion(key, designerVersion); + } + log.info("updating installation count for product {}", key); if (BooleanUtils.isTrue(product.getSynchronizedInstallationCount())) { return productRepository.increaseInstallationCount(key); } syncInstallationCountWithProduct(product); - if (StringUtils.isNotBlank(designerVersion)) { - productRepository.increaseInstallationCountForProductByDesignerVersion(key, designerVersion); - } return productRepository.updateInitialCount(key, product.getInstallationCount() + 1); } diff --git a/marketplace-service/src/test/java/com/axonivy/market/repository/impl/CustomProductRepositoryImplTest.java b/marketplace-service/src/test/java/com/axonivy/market/repository/impl/CustomProductRepositoryImplTest.java index 4d9fb26db..3938e5d54 100644 --- a/marketplace-service/src/test/java/com/axonivy/market/repository/impl/CustomProductRepositoryImplTest.java +++ b/marketplace-service/src/test/java/com/axonivy/market/repository/impl/CustomProductRepositoryImplTest.java @@ -3,6 +3,7 @@ import com.axonivy.market.BaseSetup; import com.axonivy.market.constants.MongoDBConstants; import com.axonivy.market.entity.Product; +import com.axonivy.market.entity.ProductDesignerInstallation; import com.axonivy.market.repository.ProductModuleContentRepository; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -132,4 +133,10 @@ void testUpdateInitialCount() { repo.updateInitialCount(ID, initialCount); verify(mongoTemplate).updateFirst(any(Query.class), eq(new Update().inc("InstallationCount", initialCount).set("SynchronizedInstallationCount", true)), eq(Product.class)); } + + @Test + void testIncreaseInstallationCountForProductByDesignerVersion() { + repo.increaseInstallationCountForProductByDesignerVersion("portal", "10.0.20"); + verify(mongoTemplate).upsert(any(Query.class), any(Update.class), eq(ProductDesignerInstallation.class)); + } } diff --git a/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java b/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java index 34359cefc..4134fe92f 100644 --- a/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java +++ b/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java @@ -150,6 +150,11 @@ void testUpdateInstallationCountForProduct() { when(productRepository.increaseInstallationCount(product.getId())).thenReturn(31); result = productService.updateInstallationCountForProduct(product.getId(), "10.0.20"); assertEquals(31, result); + + product.setSynchronizedInstallationCount(false); + when(productRepository.updateInitialCount(product.getId(), 31)).thenReturn(32); + result = productService.updateInstallationCountForProduct(product.getId(), "10.0.20"); + assertEquals(32, result); } @Test From 5e0031e08a0033855fcad5e4d1e6d4fef89a012e Mon Sep 17 00:00:00 2001 From: PHAM HOANG HUNG Date: Fri, 6 Sep 2024 14:57:39 +0700 Subject: [PATCH 10/17] Fix test --- .../market/service/impl/ProductServiceImplTest.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java b/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java index 4134fe92f..8c0e4a7de 100644 --- a/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java +++ b/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java @@ -142,19 +142,15 @@ public void setup() { @Test void testUpdateInstallationCountForProduct() { - int result = productService.updateInstallationCountForProduct(null, "10.0.20"); + String designerVersion = "10.0.20"; + int result = productService.updateInstallationCountForProduct(null, designerVersion); assertEquals(0, result); Product product = mockProduct(); when(productRepository.getProductById(product.getId())).thenReturn(product); when(productRepository.increaseInstallationCount(product.getId())).thenReturn(31); - result = productService.updateInstallationCountForProduct(product.getId(), "10.0.20"); + result = productService.updateInstallationCountForProduct(product.getId(), designerVersion); assertEquals(31, result); - - product.setSynchronizedInstallationCount(false); - when(productRepository.updateInitialCount(product.getId(), 31)).thenReturn(32); - result = productService.updateInstallationCountForProduct(product.getId(), "10.0.20"); - assertEquals(32, result); } @Test From 6bdc0a759547f42d88e29915125496b3d654be9a Mon Sep 17 00:00:00 2001 From: PHAM HOANG HUNG Date: Fri, 6 Sep 2024 15:05:04 +0700 Subject: [PATCH 11/17] Fix test --- .../axonivy/market/service/impl/ProductServiceImplTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java b/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java index 8c0e4a7de..5e473b619 100644 --- a/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java +++ b/marketplace-service/src/test/java/com/axonivy/market/service/impl/ProductServiceImplTest.java @@ -151,6 +151,9 @@ void testUpdateInstallationCountForProduct() { when(productRepository.increaseInstallationCount(product.getId())).thenReturn(31); result = productService.updateInstallationCountForProduct(product.getId(), designerVersion); assertEquals(31, result); + + result = productService.updateInstallationCountForProduct(product.getId(), ""); + assertEquals(31, result); } @Test From 4f82f44c434a4977e274ebb2a35db470f1e86a06 Mon Sep 17 00:00:00 2001 From: PHAM HOANG HUNG Date: Fri, 6 Sep 2024 15:47:55 +0700 Subject: [PATCH 12/17] Handle feedback --- .../modules/product/product.service.spec.ts | 18 +++--------------- .../src/app/modules/product/product.service.ts | 2 +- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/marketplace-ui/src/app/modules/product/product.service.spec.ts b/marketplace-ui/src/app/modules/product/product.service.spec.ts index 541e1ceff..212ca073a 100644 --- a/marketplace-ui/src/app/modules/product/product.service.spec.ts +++ b/marketplace-ui/src/app/modules/product/product.service.spec.ts @@ -215,12 +215,13 @@ describe('ProductService', () => { it('sendRequestToUpdateInstallationCount', () => { const productId = "google-maps-connector"; + const designerVersion = "10.0.0"; - service.sendRequestToUpdateInstallationCount(productId).subscribe(response => { + service.sendRequestToUpdateInstallationCount(productId, designerVersion).subscribe(response => { expect(response).toBe(3); }); - const req = httpMock.expectOne(`api/product-details/installationcount/${productId}`); + const req = httpMock.expectOne(`api/product-details/installationcount/${productId}?designerVersion=${designerVersion}`); expect(req.request.method).toBe('PUT'); expect(req.request.headers.get('X-Requested-By')).toBe('ivy'); req.flush(3); @@ -242,17 +243,4 @@ describe('ProductService', () => { req.flush([{ version: '10.0.2' }, {version: '10.0.1'}, {version: '10.0.0'}]); }); - it('should call sendRequestToUpdateInstallationCountByDesignerVersion and return true', () => { - const productId = 'google-maps-connector'; - const designerVersion = '11.4.0'; - - service.sendRequestToUpdateInstallationCountByDesignerVersion(designerVersion, productId).subscribe(response => { - expect(response).toBeTruthy(); - }); - - const req = httpMock.expectOne(`api/product-details/installation/${productId}/designer/${designerVersion}`); - expect(req.request.method).toBe('PUT'); - expect(req.request.headers.get('X-Requested-By')).toBe('ivy'); - req.flush(true); - }); }); diff --git a/marketplace-ui/src/app/modules/product/product.service.ts b/marketplace-ui/src/app/modules/product/product.service.ts index 9dafac5d6..1a46392a0 100644 --- a/marketplace-ui/src/app/modules/product/product.service.ts +++ b/marketplace-ui/src/app/modules/product/product.service.ts @@ -80,7 +80,7 @@ export class ProductService { const url = 'api/product-details/installationcount/' + productId; return this.httpClient.put(url, null, { headers: { 'X-Requested-By': 'ivy' }, - params: { 'designerVersion:': designerVersion } + params: { 'designerVersion': designerVersion } }); } From bb49ac286de65501e35366493cbfd849cec42c76 Mon Sep 17 00:00:00 2001 From: PHAM HOANG HUNG Date: Fri, 6 Sep 2024 15:59:32 +0700 Subject: [PATCH 13/17] Fix sonar --- marketplace-ui/src/app/modules/product/product.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/marketplace-ui/src/app/modules/product/product.service.ts b/marketplace-ui/src/app/modules/product/product.service.ts index 1a46392a0..a7fd27fa7 100644 --- a/marketplace-ui/src/app/modules/product/product.service.ts +++ b/marketplace-ui/src/app/modules/product/product.service.ts @@ -80,7 +80,7 @@ export class ProductService { const url = 'api/product-details/installationcount/' + productId; return this.httpClient.put(url, null, { headers: { 'X-Requested-By': 'ivy' }, - params: { 'designerVersion': designerVersion } + params: { designerVersion: designerVersion } }); } From 6ad39771355d6110e58c4ac221c14c28a82d4f0d Mon Sep 17 00:00:00 2001 From: PHAM HOANG HUNG Date: Fri, 6 Sep 2024 16:04:32 +0700 Subject: [PATCH 14/17] fix sonar --- marketplace-ui/src/app/modules/product/product.service.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/marketplace-ui/src/app/modules/product/product.service.ts b/marketplace-ui/src/app/modules/product/product.service.ts index a7fd27fa7..86318c9e3 100644 --- a/marketplace-ui/src/app/modules/product/product.service.ts +++ b/marketplace-ui/src/app/modules/product/product.service.ts @@ -78,10 +78,11 @@ export class ProductService { sendRequestToUpdateInstallationCount(productId: string, designerVersion: string) { const url = 'api/product-details/installationcount/' + productId; - return this.httpClient.put(url, null, { + const options = { headers: { 'X-Requested-By': 'ivy' }, - params: { designerVersion: designerVersion } - }); + params: { 'designerVersion': designerVersion } + }; + return this.httpClient.put(url, null, options); } sendRequestToGetProductVersionsForDesigner(productId: string) { From a6d3c3f3fe9539b67733bb1463ecb7184d35407b Mon Sep 17 00:00:00 2001 From: PHAM HOANG HUNG Date: Fri, 6 Sep 2024 16:10:45 +0700 Subject: [PATCH 15/17] fix sonar --- marketplace-ui/src/app/modules/product/product.service.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/marketplace-ui/src/app/modules/product/product.service.ts b/marketplace-ui/src/app/modules/product/product.service.ts index 86318c9e3..7cdd6179d 100644 --- a/marketplace-ui/src/app/modules/product/product.service.ts +++ b/marketplace-ui/src/app/modules/product/product.service.ts @@ -78,9 +78,11 @@ export class ProductService { sendRequestToUpdateInstallationCount(productId: string, designerVersion: string) { const url = 'api/product-details/installationcount/' + productId; + const headers = { 'X-Requested-By': 'ivy' }; + const params = { designerVersion: designerVersion }; const options = { - headers: { 'X-Requested-By': 'ivy' }, - params: { 'designerVersion': designerVersion } + headers, + params }; return this.httpClient.put(url, null, options); } From 895d6926f25b677cf99a3d1340496926c42d5ba5 Mon Sep 17 00:00:00 2001 From: PHAM HOANG HUNG Date: Fri, 6 Sep 2024 16:23:26 +0700 Subject: [PATCH 16/17] Fix sonar --- marketplace-ui/src/app/modules/product/product.service.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/marketplace-ui/src/app/modules/product/product.service.ts b/marketplace-ui/src/app/modules/product/product.service.ts index 7cdd6179d..49f11c76f 100644 --- a/marketplace-ui/src/app/modules/product/product.service.ts +++ b/marketplace-ui/src/app/modules/product/product.service.ts @@ -89,6 +89,8 @@ export class ProductService { sendRequestToGetProductVersionsForDesigner(productId: string) { const url = `api/product-details/${productId}/designerversions`; - return this.httpClient.get(url, { headers: { 'X-Requested-By': 'ivy' } }); + const headers = { 'X-Requested-By': 'ivy' }; + const options = { headers }; + return this.httpClient.get(url, options); } } From 1d67ec871d760f9bca1aff950d45f7f889f66279 Mon Sep 17 00:00:00 2001 From: PHAM HOANG HUNG Date: Fri, 6 Sep 2024 16:39:30 +0700 Subject: [PATCH 17/17] Fix sonar --- .../src/app/modules/product/product.service.ts | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/marketplace-ui/src/app/modules/product/product.service.ts b/marketplace-ui/src/app/modules/product/product.service.ts index 49f11c76f..9ecbebff4 100644 --- a/marketplace-ui/src/app/modules/product/product.service.ts +++ b/marketplace-ui/src/app/modules/product/product.service.ts @@ -79,18 +79,12 @@ export class ProductService { sendRequestToUpdateInstallationCount(productId: string, designerVersion: string) { const url = 'api/product-details/installationcount/' + productId; const headers = { 'X-Requested-By': 'ivy' }; - const params = { designerVersion: designerVersion }; - const options = { - headers, - params - }; - return this.httpClient.put(url, null, options); + const params = new HttpParams().append('designerVersion', designerVersion); + return this.httpClient.put(url, null, { headers, params }); } sendRequestToGetProductVersionsForDesigner(productId: string) { const url = `api/product-details/${productId}/designerversions`; - const headers = { 'X-Requested-By': 'ivy' }; - const options = { headers }; - return this.httpClient.get(url, options); + return this.httpClient.get(url, { headers: { 'X-Requested-By': 'ivy' } }); } }