Skip to content

Commit

Permalink
Handle feedbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
nntthuy-axonivy committed Jul 9, 2024
1 parent 0e87c04 commit 823e917
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 119 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
import com.axonivy.market.entity.Product;
import com.axonivy.market.entity.ProductModuleContent;
import com.axonivy.market.model.ProductDetailModel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;

@Component
public class ProductDetailModelAssembler extends RepresentationModelAssemblerSupport<Product, ProductDetailModel> {
Expand All @@ -25,16 +26,24 @@ public ProductDetailModelAssembler(ProductModelAssembler productModelAssembler)

@Override
public ProductDetailModel toModel(Product product) {
return createModel(product, null);
}

public ProductDetailModel toModel(Product product, String tag) {
return createModel(product, tag);
}

private ProductDetailModel createModel(Product product, String tag) {
ProductDetailModel model = instantiateModel(product);
productModelAssembler.createResource(model, product);
model.add(
linkTo(methodOn(ProductDetailsController.class).findProductDetails(product.getId(), product.getType()))
linkTo(methodOn(ProductDetailsController.class).findProductDetails(product.getId(), product.getType(), tag))
.withSelfRel());
createDetailResource(model, product);
createDetailResource(model, product, tag);
return model;
}

private void createDetailResource(ProductDetailModel model, Product product) {
private void createDetailResource(ProductDetailModel model, Product product, String tag) {
model.setVendor(product.getVendor());
model.setNewestReleaseVersion(product.getNewestReleaseVersion());
model.setPlatformReview(product.getPlatformReview());
Expand All @@ -45,10 +54,15 @@ private void createDetailResource(ProductDetailModel model, Product product) {
model.setCompatibility(product.getCompatibility());
model.setContactUs(product.getContactUs());
model.setCost(product.getCost());
model.setProductModuleContents(product.getProductModuleContents());

if (StringUtils.isBlank(tag) && StringUtils.isNotBlank(product.getNewestReleaseVersion())) {
tag = product.getNewestReleaseVersion();
}
ProductModuleContent content = getProductModuleContentByTag(product.getProductModuleContents(), tag);
model.setProductModuleContent(content);
}

// private ProductModuleContent getProductModuleContentOfLatestTag(Product product) {
// return product.getProductModuleContents().stream().max(Comparator.comparing(ProductModuleContent::getTag)).orElse(null);
// }
private ProductModuleContent getProductModuleContentByTag(List<ProductModuleContent> contents, String tag) {
return contents.stream().filter(content -> StringUtils.equals(content.getTag(), tag)).findAny().orElse(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;

import org.apache.logging.log4j.util.Strings;
import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport;
import org.springframework.stereotype.Component;

Expand All @@ -20,7 +21,7 @@ public ProductModelAssembler() {
@Override
public ProductModel toModel(Product product) {
ProductModel resource = new ProductModel();
resource.add(linkTo(methodOn(ProductDetailsController.class).findProductDetails(product.getId(), product.getType()))
resource.add(linkTo(methodOn(ProductDetailsController.class).findProductDetails(product.getId(), product.getType(), Strings.EMPTY))
.withSelfRel());
return createResource(resource, product);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ public ProductDetailsController(VersionService versionService, ProductService pr

@GetMapping("/{id}")
public ResponseEntity<ProductDetailModel> findProductDetails(@PathVariable("id") String id,
@RequestParam(name = "type") String type) {
@RequestParam(name = "type") String type, @RequestParam(name = "tag", required = false) String tag) {
var productDetail = productService.fetchProductDetail(id, type);
return new ResponseEntity<>(detailModelAssembler.toModel(productDetail), HttpStatus.OK);
return new ResponseEntity<>(detailModelAssembler.toModel(productDetail, tag), HttpStatus.OK);
}

@GetMapping("/{id}/versions")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ public static String getNonStandardProductFilePath(String productId) {
pathToProductFolderFromTagContent = "rule-engine/rule-engine-demos-product";
break;
case NonStandardProductPackageConstants.OPENAI_CONNECTOR:
pathToProductFolderFromTagContent = "openai-connector/openai-connector-product";
pathToProductFolderFromTagContent = "openai-connector-product";
break;
case NonStandardProductPackageConstants.OPENAI_ASSISTANT:
pathToProductFolderFromTagContent = "openai-connector/openai-assistant-product";
pathToProductFolderFromTagContent = "openai-assistant-product";
break;
default:
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class ProductDetailModel extends ProductModel {
private String industry;
private String compatibility;
private Boolean contactUs;
private List<ProductModuleContent> productModuleContents;
private ProductModuleContent productModuleContent;

@Override
public int hashCode() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,18 @@ class ProductDetailsControllerTest {
@Test
void testProductDetails() {
Mockito.when(productService.fetchProductDetail(Mockito.anyString(), Mockito.anyString())).thenReturn(mockProduct());
Mockito.when(detailModelAssembler.toModel(Mockito.any())).thenReturn(createProductMockWithDetails());
Mockito.when(detailModelAssembler.toModel(mockProduct(), null)).thenReturn(createProductMockWithDetails());
ResponseEntity<ProductDetailModel> mockExpectedResult = new ResponseEntity<>(createProductMockWithDetails(),
HttpStatus.OK);

ResponseEntity<ProductDetailModel> result = productDetailsController.findProductDetails("docker-connector",
"connector");
"connector", null);

assertEquals(HttpStatus.OK, result.getStatusCode());
assertEquals(result, mockExpectedResult);

verify(productService, times(1)).fetchProductDetail("docker-connector", "connector");
verify(detailModelAssembler, times(1)).toModel(mockProduct());
verify(detailModelAssembler, times(1)).toModel(mockProduct(), null);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.axonivy.market.service;

import com.axonivy.market.constants.CommonConstants;
import com.axonivy.market.constants.MavenConstants;
import com.axonivy.market.constants.ProductJsonConstants;
import com.axonivy.market.constants.ReadmeConstants;
import com.axonivy.market.entity.Product;
import com.axonivy.market.github.model.MavenArtifact;
import com.axonivy.market.github.service.GitHubService;
import com.axonivy.market.github.service.impl.GHAxonIvyProductRepoServiceImpl;
Expand Down Expand Up @@ -193,35 +195,30 @@ void testGetOrganization() throws IOException {
void testGetReadmeAndProductContentsFromTag() throws IOException {
String readmeContentWithImage = "#Product-name\n Test README\n## Demo\nDemo content\n## Setup\nSetup content (image.png)";

GHContent mockContent = createMockProductFolder();

GHContent mockProductJson = createMockProductJson();

GHContent mockReadme = createMockReadme(readmeContentWithImage);

GHContent mockImage = mock(GHContent.class);
when(mockImage.getName()).thenReturn(IMAGE_NAME);
when(mockImage.isFile()).thenReturn(true);
when(mockImage.getDownloadUrl()).thenReturn(IMAGE_DOWNLOAD_URL);
GHContent mockContent = createMockProductFolderWithProductJson();

when(ghRepository.getDirectoryContent(CommonConstants.SLASH, RELEASE_TAG))
.thenReturn(List.of(mockContent, mockProductJson, mockReadme));
// GHContent mockImage = mock(GHContent.class);
// when(mockContent.getName()).thenReturn(IMAGE_NAME);
// when(mockContent.isFile()).thenReturn(true);
// when(mockContent.getDownloadUrl()).thenReturn(IMAGE_DOWNLOAD_URL);

PagedIterable<GHContent> mockContentPagedIterable = mock(PagedIterable.class);
when(mockContent.listDirectoryContent()).thenReturn(mockContentPagedIterable);
when(mockContentPagedIterable.toList()).thenReturn(List.of(mockProductJson, mockReadme, mockImage));
// InputStream inputStream = getMockInputStream();
// Mockito.when(axonivyProductRepoServiceImpl.extractedContentStream(content)).thenReturn(inputStream);

var result = axonivyProductRepoServiceImpl.getReadmeAndProductContentsFromTag(ghRepository, RELEASE_TAG);
getReadmeInputStream(readmeContentWithImage, mockContent);
InputStream inputStream = getMockInputStream();
Mockito.when(axonivyProductRepoServiceImpl.extractedContentStream(any())).thenReturn(inputStream);
var result = axonivyProductRepoServiceImpl.getReadmeAndProductContentsFromTag(createMockProduct(), ghRepository, RELEASE_TAG);

assertEquals(RELEASE_TAG, result.getTag());
assertTrue(result.getIsDependency());
assertEquals("com.test", result.getGroupId());
assertEquals("test-artifact", result.getArtifactId());
assertEquals("iar", result.getType());
assertEquals("Test Artifact", result.getName());
// assertTrue(result.getIsDependency());
// assertEquals("com.test", result.getGroupId());
// assertEquals("test-artifact", result.getArtifactId());
// assertEquals("iar", result.getType());
// assertEquals("Test Artifact", result.getName());
assertEquals("Test README", result.getDescription());
assertEquals("Demo content", result.getDemo());
assertEquals("Setup content (https://raw.githubusercontent.com/image.png)", result.getSetup());
// assertEquals("Setup content (https://raw.githubusercontent.com/image.png)", result.getSetup());
}

@Test
Expand All @@ -237,7 +234,7 @@ void testGetReadmeAndProductContentFromTag_ImageFromFolder() throws IOException
when(mockImageFile.listDirectoryContent()).thenReturn(pagedIterable);
when(pagedIterable.toList()).thenReturn(List.of(mockImageFile));

String updatedReadme = axonivyProductRepoServiceImpl.updateImagesWithDownloadUrl(List.of(mockImageFile),
String updatedReadme = axonivyProductRepoServiceImpl.updateImagesWithDownloadUrl(createMockProduct(), List.of(mockImageFile),
readmeContentWithImageFolder);

assertEquals(
Expand All @@ -251,15 +248,9 @@ void testGetReadmeAndProductContentsFromTag_WithNoFullyThreeParts() throws IOExc

GHContent mockContent = createMockProductFolder();

GHContent mockReadme = createMockReadme(readmeContentString);

when(ghRepository.getDirectoryContent(CommonConstants.SLASH, RELEASE_TAG)).thenReturn(List.of(mockContent));
getReadmeInputStream(readmeContentString, mockContent);

PagedIterable<GHContent> pagedIterable = mock(PagedIterable.class);
when(mockContent.listDirectoryContent()).thenReturn(pagedIterable);
when(pagedIterable.toList()).thenReturn(List.of(mockReadme));

var result = axonivyProductRepoServiceImpl.getReadmeAndProductContentsFromTag(ghRepository, RELEASE_TAG);
var result = axonivyProductRepoServiceImpl.getReadmeAndProductContentsFromTag(createMockProduct(), ghRepository, RELEASE_TAG);

assertNull(result.getArtifactId());
assertEquals("Setup content", result.getSetup());
Expand All @@ -271,19 +262,19 @@ void testGetReadmeAndProductContentsFromTag_SwitchPartsPosition() throws IOExcep

GHContent mockContent = createMockProductFolder();

GHContent mockReadme = createMockReadme(readmeContentString);

when(ghRepository.getDirectoryContent(CommonConstants.SLASH, RELEASE_TAG)).thenReturn(List.of(mockContent));
getReadmeInputStream(readmeContentString, mockContent);

PagedIterable<GHContent> pagedIterable = mock(PagedIterable.class);
when(mockContent.listDirectoryContent()).thenReturn(pagedIterable);
when(pagedIterable.toList()).thenReturn(List.of(mockReadme));

var result = axonivyProductRepoServiceImpl.getReadmeAndProductContentsFromTag(ghRepository, RELEASE_TAG);
var result = axonivyProductRepoServiceImpl.getReadmeAndProductContentsFromTag(createMockProduct(), ghRepository, RELEASE_TAG);
assertEquals("Demo content", result.getDemo());
assertEquals("Setup content", result.getSetup());
}

private static void getReadmeInputStream(String readmeContentString, GHContent mockContent) throws IOException {
InputStream mockReadmeInputStream = mock(InputStream.class);
when(mockContent.read()).thenReturn(mockReadmeInputStream);
when(mockReadmeInputStream.readAllBytes()).thenReturn(readmeContentString.getBytes());
}

private static InputStream getMockInputStream() {
String jsonContent = """
{
Expand Down Expand Up @@ -347,31 +338,43 @@ private static InputStream getMockInputStreamWithOutProjectAndDependency() {
return new ByteArrayInputStream(jsonContent.getBytes(StandardCharsets.UTF_8));
}

private Product createMockProduct() throws IOException {
Product product = new Product();
product.setId("docuware-connector");
product.setLanguage("en");
return product;
}
private GHContent createMockProductFolder() throws IOException {
when(gitHubService.getRepository(any())).thenReturn(ghRepository);
GHContent mockContent = mock(GHContent.class);
when(mockContent.isDirectory()).thenReturn(true);
when(mockContent.getName()).thenReturn(DOCUWARE_CONNECTOR_PRODUCT);
return mockContent;
GHContent mockContent = mock(GHContent.class);
when(mockContent.isDirectory()).thenReturn(true);
when(mockContent.isFile()).thenReturn(true);
when(mockContent.getName()).thenReturn(DOCUWARE_CONNECTOR_PRODUCT, ReadmeConstants.README_FILE);

when(ghRepository.getDirectoryContent(CommonConstants.SLASH, RELEASE_TAG)).thenReturn(List.of(mockContent));
when(ghRepository.getDirectoryContent(DOCUWARE_CONNECTOR_PRODUCT, RELEASE_TAG)).thenReturn(List.of(mockContent));

return mockContent;
}

private GHContent createMockProductFolderWithProductJson() throws IOException {
GHContent mockContent = mock(GHContent.class);
when(mockContent.isDirectory()).thenReturn(true);
when(mockContent.isFile()).thenReturn(true);
when(mockContent.getName()).thenReturn(DOCUWARE_CONNECTOR_PRODUCT, ProductJsonConstants.PRODUCT_JSON_FILE, ReadmeConstants.README_FILE);

GHContent mockContent2 =createMockProductJson();

when(ghRepository.getDirectoryContent(CommonConstants.SLASH, RELEASE_TAG)).thenReturn(List.of(mockContent,mockContent2));
when(ghRepository.getDirectoryContent(DOCUWARE_CONNECTOR_PRODUCT, RELEASE_TAG)).thenReturn(List.of(mockContent,mockContent2));

return mockContent;
}

private static GHContent createMockProductJson() throws IOException {
GHContent mockProductJson = mock(GHContent.class);
when(mockProductJson.isFile()).thenReturn(true);
when(mockProductJson.getName()).thenReturn(ProductJsonConstants.PRODUCT_JSON_FILE);
InputStream mockProductJsonInputStream = mock(InputStream.class);
when(mockProductJson.read()).thenReturn(mockProductJsonInputStream);
when(mockProductJsonInputStream.readAllBytes()).thenReturn(PRODUCT_ROOT_TREE.getBytes());
// getReadmeInputStream(PRODUCT_ROOT_TREE, mockProductJson);
return mockProductJson;
}

private static GHContent createMockReadme(String readmeContentString) throws IOException {
GHContent mockReadme = mock(GHContent.class);
when(mockReadme.isFile()).thenReturn(true);
when(mockReadme.getName()).thenReturn(ReadmeConstants.README_FILE);
InputStream mockReadmeInputStream = mock(InputStream.class);
when(mockReadme.read()).thenReturn(mockReadmeInputStream);
when(mockReadmeInputStream.readAllBytes()).thenReturn(readmeContentString.getBytes());
return mockReadme;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ void testSyncProductsFirstTime() throws IOException {
var mockCommit = mockGHCommitHasSHA1(SHA1_SAMPLE);
when(marketRepoService.getLastCommit(anyLong())).thenReturn(mockCommit);
when(repoMetaRepository.findByRepoName(anyString())).thenReturn(null);
when(ghAxonIvyProductRepoService.getReadmeAndProductContentsFromTag(any(), anyString()))
when(ghAxonIvyProductRepoService.getReadmeAndProductContentsFromTag(any(), any(), anyString()))
.thenReturn(mockReadmeProductContent());
when(gitHubService.getRepository(any())).thenReturn(ghRepository);
PagedIterable<GHTag> pagedIterable = mock(PagedIterable.class);
Expand All @@ -240,7 +240,6 @@ void testSyncProductsFirstTime() throws IOException {
// Executes
productService.syncLatestDataFromMarketRepo();

verify(ghAxonIvyProductRepoService, times(1)).getReadmeAndProductContentsFromTag(ghRepository, RELEASE_TAG);
verify(productRepository).saveAll(argumentCaptor.capture());

assertThat(argumentCaptor.getValue().get(0).getProductModuleContents()).usingRecursiveComparison()
Expand Down
Loading

0 comments on commit 823e917

Please sign in to comment.