Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/marp 975 display compatibility range in marketplace items #260

tvtphuc-axonivy marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
import com.axonivy.market.entity.Product;
import com.axonivy.market.model.ProductDetailModel;
import com.axonivy.market.util.ImageUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Optional;

import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
Expand Down Expand Up @@ -79,6 +81,7 @@ private void createDetailResource(ProductDetailModel model, Product product) {
model.setContactUs(product.getContactUs());
model.setCost(product.getCost());
model.setInstallationCount(product.getInstallationCount());
model.setCompatibilityRange(product.getCompatibilityRange());
model.setProductModuleContent(ImageUtils.mappingImageForProductModuleContent(product.getProductModuleContent()));
if (StringUtils.isNotBlank(product.getVendorImage())) {
Link vendorLink = linkTo(methodOn(ImageController.class).findImageById(product.getVendorImage())).withSelfRel();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ public class Product implements Serializable {
private String bestMatchVersion;
@Transient
private boolean isMavenDropins;
@Transient
private String compatibilityRange;

@Override
public int hashCode() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public class ProductDetailModel extends ProductModel {
private int installationCount;
@Schema(description = "The api url to get metadata from product.json")
private String metaProductJsonUrl;
private String compatibilityRange;
private boolean isMavenDropins;

@Override
Expand Down
tvtphuc-axonivy marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@
import com.axonivy.market.github.service.GHAxonIvyProductRepoService;
import com.axonivy.market.github.service.GitHubService;
import com.axonivy.market.github.util.GitHubUtils;
import com.axonivy.market.model.VersionAndUrlModel;
import com.axonivy.market.repository.*;
import com.axonivy.market.service.ExternalDocumentService;
import com.axonivy.market.service.ImageService;
import com.axonivy.market.service.MetadataService;
import com.axonivy.market.service.ProductContentService;
import com.axonivy.market.service.ProductMarketplaceDataService;
import com.axonivy.market.service.ProductService;
import com.axonivy.market.service.VersionService;
import com.axonivy.market.util.MavenUtils;
import com.axonivy.market.util.MetadataReaderUtils;
import com.axonivy.market.util.VersionUtils;
Expand Down Expand Up @@ -60,7 +62,7 @@
import java.time.format.DateTimeFormatter;
import java.util.*;

import static com.axonivy.market.constants.CommonConstants.SLASH;
import static com.axonivy.market.constants.CommonConstants.*;
import static com.axonivy.market.constants.MavenConstants.*;
import static com.axonivy.market.constants.ProductJsonConstants.EN_LANGUAGE;
import static com.axonivy.market.constants.ProductJsonConstants.LOGO_FILE;
Expand Down Expand Up @@ -94,6 +96,7 @@ public class ProductServiceImpl implements ProductService {
private final ProductMarketplaceDataService productMarketplaceDataService;
private final ProductMarketplaceDataRepository productMarketplaceDataRepo;
private GHCommit lastGHCommit;
private VersionService versionService;
private GitHubRepoMeta marketRepoMeta;
@Value("${market.github.market.branch}")
private String marketRepoBranch;
Expand All @@ -106,7 +109,7 @@ public ProductServiceImpl(ProductRepository productRepo, ProductModuleContentRep
MetadataSyncRepository metadataSyncRepo, MetadataRepository metadataRepo, ImageService imageService,
ProductContentService productContentService, MetadataService metadataService,
ProductMarketplaceDataService productMarketplaceDataService, ExternalDocumentService externalDocumentService,
ProductMarketplaceDataRepository productMarketplaceDataRepo) {
ProductMarketplaceDataRepository productMarketplaceDataRepo, VersionService versionService) {
this.productRepo = productRepo;
this.productModuleContentRepo = productModuleContentRepo;
this.axonIvyMarketRepoService = axonIvyMarketRepoService;
Expand All @@ -125,6 +128,7 @@ public ProductServiceImpl(ProductRepository productRepo, ProductModuleContentRep
this.productMarketplaceDataService = productMarketplaceDataService;
this.externalDocumentService = externalDocumentService;
this.productMarketplaceDataRepo = productMarketplaceDataRepo;
this.versionService = versionService;
}

@Override
Expand Down Expand Up @@ -582,15 +586,15 @@ public String getCompatibilityFromOldestVersion(String oldestVersion) {
if (StringUtils.isBlank(oldestVersion)) {
return Strings.EMPTY;
}
if (!oldestVersion.contains(CommonConstants.DOT_SEPARATOR)) {
if (!oldestVersion.contains(DOT_SEPARATOR)) {
return oldestVersion + ".0+";
}
int firstDot = oldestVersion.indexOf(CommonConstants.DOT_SEPARATOR);
int secondDot = oldestVersion.indexOf(CommonConstants.DOT_SEPARATOR, firstDot + 1);
int firstDot = oldestVersion.indexOf(DOT_SEPARATOR);
int secondDot = oldestVersion.indexOf(DOT_SEPARATOR, firstDot + 1);
if (secondDot == -1) {
return oldestVersion.concat(CommonConstants.PLUS);
return oldestVersion.concat(PLUS);
}
return oldestVersion.substring(0, secondDot).concat(CommonConstants.PLUS);
return oldestVersion.substring(0, secondDot).concat(PLUS);
}

@Override
Expand All @@ -599,6 +603,10 @@ public Product fetchProductDetail(String id, Boolean isShowDevVersion) {
return Optional.ofNullable(product).map(productItem -> {
int installationCount = productMarketplaceDataService.updateProductInstallationCount(id);
productItem.setInstallationCount(installationCount);

String compatibilityRange = getCompatibilityRange(id);
productItem.setCompatibilityRange(compatibilityRange);

return productItem;
}).orElse(null);
}
Expand All @@ -614,6 +622,10 @@ public Product fetchBestMatchProductDetail(String id, String version) {
return Optional.ofNullable(product).map(productItem -> {
int installationCount = productMarketplaceDataService.updateProductInstallationCount(id);
productItem.setInstallationCount(installationCount);

String compatibilityRange = getCompatibilityRange(id);
productItem.setCompatibilityRange(compatibilityRange);

productItem.setBestMatchVersion(bestMatchVersion);
return productItem;
}).orElse(null);
Expand Down Expand Up @@ -749,4 +761,30 @@ public boolean syncFirstPublishedDateOfAllProducts() {
return false;
}
}

private String getCompatibilityRange(String productId) {
return Optional.of(versionService.getVersionsForDesigner(productId))
.filter(ObjectUtils::isNotEmpty)
.map(versions -> versions.stream().map(VersionAndUrlModel::getVersion).toList())
.map(versions -> {
if (versions.size() == 1) {
return splitVersion(versions.get(0)).concat(PLUS);
}
String maxValue = splitVersion(versions.get(0)).concat(PLUS);
String minValue = splitVersion(versions.get(versions.size() - 1));
tvtphuc-axonivy marked this conversation as resolved.
Show resolved Hide resolved
return getPrefixOfVersion(minValue).equals(getPrefixOfVersion(maxValue)) ?
minValue.concat(PLUS) :
minValue.concat(DASH_SEPARATOR).concat(maxValue);
}).orElse(null);
}

private String splitVersion(String version) {
int firstDot = version.indexOf(DOT_SEPARATOR);
int secondDot = version.indexOf(DOT_SEPARATOR, firstDot + 1);
return version.substring(0, secondDot);
}

private String getPrefixOfVersion(String version) {
return version.substring(0, version.indexOf(DOT_SEPARATOR));
}
tvtphuc-axonivy marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.axonivy.market.enums.Language;
import com.axonivy.market.enums.SortOption;
import com.axonivy.market.model.MavenArtifactModel;
import com.axonivy.market.model.VersionAndUrlModel;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
Expand Down Expand Up @@ -265,4 +266,56 @@ protected static ProductJsonContent getMockProductJsonContentContainMavenDropins
protected ProductMarketplaceData getMockProductMarketplaceData() {
return ProductMarketplaceData.builder().id(MOCK_PRODUCT_ID).installationCount(3).build();
}

protected List<VersionAndUrlModel> mockVersionAndUrlModels() {
VersionAndUrlModel versionAndUrlModel = VersionAndUrlModel.builder()
.version("10.0.21")
.url("/api/product-details/productjsoncontent/portal/10.0.21")
tvtphuc-axonivy marked this conversation as resolved.
Show resolved Hide resolved
.build();

VersionAndUrlModel versionAndUrlModel2 = VersionAndUrlModel.builder()
.version("10.0.22")
.url("/api/product-details/productjsoncontent/portal/10.0.22")
.build();

return List.of(versionAndUrlModel, versionAndUrlModel2);
}

protected List<VersionAndUrlModel> mockVersionModels() {
VersionAndUrlModel versionAndUrlModel = VersionAndUrlModel.builder()
.version("11.3.1")
.build();

VersionAndUrlModel versionAndUrlModel2 = VersionAndUrlModel.builder()
.version("10.0.22")
.build();

return List.of(versionAndUrlModel, versionAndUrlModel2);
}

protected List<VersionAndUrlModel> mockVersionModels2() {
VersionAndUrlModel versionAndUrlModel = VersionAndUrlModel.builder()
.version("11.3.2")
.build();

List<VersionAndUrlModel> versionAndUrlModels = new ArrayList<>(mockVersionModels());
versionAndUrlModels.add(0,versionAndUrlModel);

return versionAndUrlModels;
}

protected List<VersionAndUrlModel> mockVersionModels3() {
VersionAndUrlModel versionAndUrlModel = VersionAndUrlModel.builder()
.version("11.3.2")
.build();

VersionAndUrlModel versionAndUrlModel2 = VersionAndUrlModel.builder()
.version("12.0.0")
.build();

List<VersionAndUrlModel> versionAndUrlModels = new ArrayList<>(mockVersionModels());
versionAndUrlModels.add(0,versionAndUrlModel);
versionAndUrlModels.add(0,versionAndUrlModel2);
return versionAndUrlModels;
}
}
tvtphuc-axonivy marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -177,19 +177,7 @@ void findProductVersionsById() {
Objects.requireNonNull(result.getBody()).get(1).getUrl());
}

private List<VersionAndUrlModel> mockVersionAndUrlModels() {
VersionAndUrlModel versionAndUrlModel = VersionAndUrlModel.builder()
.version("10.0.21")
.url("/api/product-details/productjsoncontent/portal/10.0.21")
.build();

VersionAndUrlModel versionAndUrlModel2 = VersionAndUrlModel.builder()
.version("10.0.22")
.url("/api/product-details/productjsoncontent/portal/10.0.22")
.build();

return List.of(versionAndUrlModel, versionAndUrlModel2);
}


@Test
void findProductJsonContentByIdAndVersion() throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import com.axonivy.market.service.MetadataService;
import com.axonivy.market.service.ProductContentService;
import com.axonivy.market.service.ProductMarketplaceDataService;
import com.axonivy.market.service.VersionService;
import com.axonivy.market.util.MavenUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.BeforeEach;
Expand Down Expand Up @@ -129,6 +130,8 @@ class ProductServiceImplTest extends BaseSetup {
private ProductMarketplaceDataService productMarketplaceDataService;
@Mock
private ProductMarketplaceDataRepository productMarketplaceDataRepo;
@Mock
private VersionService versionService;
@InjectMocks
private ProductServiceImpl productService;

Expand Down Expand Up @@ -401,6 +404,32 @@ void testFetchProductDetail() {
assertNull(result);
}

@Test
void testGetCompatibilityRangeAfterFetchProductDetail() {
MavenArtifactVersion mockMavenArtifactVersion = getMockMavenArtifactVersionWithData();
when(mavenArtifactVersionRepo.findById(MOCK_PRODUCT_ID)).thenReturn(
Optional.ofNullable(mockMavenArtifactVersion));


when(productRepo.getProductByIdAndVersion(MOCK_PRODUCT_ID, MOCK_SNAPSHOT_VERSION))
.thenReturn(getMockProduct());
when(versionService.getVersionsForDesigner(MOCK_PRODUCT_ID))
.thenReturn(mockVersionAndUrlModels(),mockVersionModels(),mockVersionModels2(),mockVersionModels3());


Product result = productService.fetchProductDetail(MOCK_PRODUCT_ID, true);
assertEquals(result.getCompatibilityRange(),"10.0+");

result = productService.fetchProductDetail(MOCK_PRODUCT_ID, true);
assertEquals(result.getCompatibilityRange(),"10.0-11.3+");

result = productService.fetchProductDetail(MOCK_PRODUCT_ID, true);
assertEquals(result.getCompatibilityRange(),"10.0-11.3+");
tvtphuc-axonivy marked this conversation as resolved.
Show resolved Hide resolved

result = productService.fetchProductDetail(MOCK_PRODUCT_ID, true);
assertEquals(result.getCompatibilityRange(),"10.0-12.0+");
}

@Test
void testGetProductByIdWithNewestReleaseVersion() {
MavenArtifactVersion mockMavenArtifactVersion = getMockMavenArtifactVersionWithData();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,14 @@ <h3 [lang]="languageService.selectedLanguage()" class="info-title text-primary">
alt="Logo Vendor"/>
</a>
</div>
<hr class="border-top-0" />
<div class="d-flex flex-row justify-content-between p-0">
<span [lang]="languageService.selectedLanguage()" class="text-secondary">
{{ 'common.product.detail.information.value.version' | translate }}
</span>
<span class="text-primary">
{{ displayVersion }}
</span>
</div>
@if(productDetail.compatibility) {
@if(productDetail?.compatibilityRange) {
<hr class="border-top-0" />
<div class="d-flex flex-row justify-content-between p-0">
<span [lang]="languageService.selectedLanguage()" class="text-secondary">
{{ 'common.product.detail.information.value.compatibility' | translate }}
</span>
<span class="text-primary">
{{ productDetail.compatibility }}
{{ productDetail.compatibilityRange }}
</span>
</div>
}
Expand Down Expand Up @@ -70,6 +61,15 @@ <h3 [lang]="languageService.selectedLanguage()" class="info-title text-primary">
<span class="text-primary text-capitalize">{{ productDetail.type }}</span>
</div>
<hr class="border-top-0" />
<div class="d-flex flex-row justify-content-between p-0">
<span [lang]="languageService.selectedLanguage()" class="text-secondary">
{{ 'common.product.detail.information.value.version' | translate }}
</span>
<span class="text-primary">
{{ displayVersion }}
</span>
</div>
<hr class="border-top-0" />
<div class="d-flex flex-row justify-content-between p-0">
<span [lang]="languageService.selectedLanguage()" class="text-secondary">
{{ 'common.product.detail.information.value.tag' | translate }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface ProductDetail {
productModuleContent: ProductModuleContent;
mavenDropins: boolean;
metaProductJsonUrl?: string;
compatibilityRange?: string;
_links: {
self: {
href: string;
Expand Down
Loading