diff --git a/dotCMS/src/main/java/com/dotmarketing/portlets/categories/business/CategoryAPI.java b/dotCMS/src/main/java/com/dotmarketing/portlets/categories/business/CategoryAPI.java index 4159ddcad20f..8ff3f200b8da 100644 --- a/dotCMS/src/main/java/com/dotmarketing/portlets/categories/business/CategoryAPI.java +++ b/dotCMS/src/main/java/com/dotmarketing/portlets/categories/business/CategoryAPI.java @@ -494,7 +494,6 @@ Category findByVariable(final String variable, final User user, * * @return List of Category filtered */ - PaginatedCategories findAll(final CategorySearchCriteria searchCriteria, - final User user, boolean respectFrontendRoles) + PaginatedCategories findAll(final CategorySearchCriteria searchCriteria, final User user, boolean respectFrontendRoles) throws DotDataException, DotSecurityException; } diff --git a/dotCMS/src/main/java/com/dotmarketing/portlets/categories/business/CategoryAPIImpl.java b/dotCMS/src/main/java/com/dotmarketing/portlets/categories/business/CategoryAPIImpl.java index 3bddeb99206c..fab12f505b88 100644 --- a/dotCMS/src/main/java/com/dotmarketing/portlets/categories/business/CategoryAPIImpl.java +++ b/dotCMS/src/main/java/com/dotmarketing/portlets/categories/business/CategoryAPIImpl.java @@ -970,7 +970,9 @@ public PaginatedCategories findAll(final CategorySearchCriteria searchCriteria, throw new IllegalArgumentException("Limit must be greater than 0"); } - final List categories = permissionAPI.filterCollection(categoryFactory.findAll(searchCriteria), + final List allCategories = new ArrayList<>(categoryFactory.findAll(searchCriteria)); + + final List categories = permissionAPI.filterCollection(allCategories, PermissionAPI.PERMISSION_READ, respectFrontendRoles, user); return getCategoriesSubList(searchCriteria.offset, searchCriteria.limit, categories, null); diff --git a/dotCMS/src/main/java/com/dotmarketing/portlets/categories/business/CategoryFactory.java b/dotCMS/src/main/java/com/dotmarketing/portlets/categories/business/CategoryFactory.java index 760933dea817..d113529ee09a 100644 --- a/dotCMS/src/main/java/com/dotmarketing/portlets/categories/business/CategoryFactory.java +++ b/dotCMS/src/main/java/com/dotmarketing/portlets/categories/business/CategoryFactory.java @@ -1,16 +1,12 @@ package com.dotmarketing.portlets.categories.business; -import java.util.Collection; + import java.util.List; -import com.dotcms.util.PaginationUtil; -import com.dotcms.util.pagination.OrderDirection; import com.dotmarketing.exception.DotDataException; import com.dotmarketing.portlets.categories.model.Category; -import com.liferay.portal.model.User; +import com.dotmarketing.portlets.categories.model.HierarchedCategory; -import javax.ws.rs.DefaultValue; -import javax.ws.rs.QueryParam; /** * @@ -287,7 +283,7 @@ public abstract class CategoryFactory { * * @param searchCriteria Search Criteria * - * @return List of Category filtered + * @return List of Category filteredx */ - public abstract List findAll(final CategorySearchCriteria searchCriteria) throws DotDataException; + public abstract List findAll(final CategorySearchCriteria searchCriteria) throws DotDataException; } diff --git a/dotCMS/src/main/java/com/dotmarketing/portlets/categories/business/CategoryFactoryImpl.java b/dotCMS/src/main/java/com/dotmarketing/portlets/categories/business/CategoryFactoryImpl.java index 7c732bd68305..31e8aeb46a1b 100644 --- a/dotCMS/src/main/java/com/dotmarketing/portlets/categories/business/CategoryFactoryImpl.java +++ b/dotCMS/src/main/java/com/dotmarketing/portlets/categories/business/CategoryFactoryImpl.java @@ -2,6 +2,8 @@ import com.dotcms.util.CloseUtils; import com.dotcms.util.DotPreconditions; +import com.dotcms.util.JsonUtil; +import com.dotcms.util.ReflectionUtils; import com.dotmarketing.beans.Tree; import com.dotmarketing.business.APILocator; import com.dotmarketing.business.CacheLocator; @@ -17,12 +19,15 @@ import com.dotmarketing.exception.DotDataException; import com.dotmarketing.factories.TreeFactory; import com.dotmarketing.portlets.categories.model.Category; +import com.dotmarketing.portlets.categories.model.HierarchedCategory; +import com.dotmarketing.portlets.categories.model.ShortCategory; import com.dotmarketing.util.InodeUtils; import com.dotmarketing.util.Logger; import com.dotmarketing.util.UtilMethods; import com.dotmarketing.util.VelocityUtil; import com.liferay.util.StringPool; +import java.io.IOException; import java.io.Serializable; import java.sql.*; import java.util.ArrayList; @@ -40,6 +45,7 @@ */ public class CategoryFactoryImpl extends CategoryFactory { + public static final String INODE = "inode"; CategoryCache catCache; final CategorySQL categorySQL; @@ -602,14 +608,13 @@ protected List findTopLevelCategoriesByFilter(String filter, String so * @param sqlResults sql query results * @return a list of categories objects */ - List convertForCategories(final List> sqlResults) { - + List convertForCategories(final List> sqlResults) { List categories = new ArrayList<>(); if ( sqlResults != null ) { for ( Map row : sqlResults ) { - Category category = convertForCategory(row); + Category category = convertForCategory(row, Category.class); categories.add(category); } } @@ -617,6 +622,45 @@ List convertForCategories(final List> sqlResults) return categories; } + private List convertForHierarchedCategories(final List> sqlResults) { + List categories = new ArrayList<>(); + + if ( sqlResults != null ) { + + for ( Map row : sqlResults ) { + HierarchedCategory category = (HierarchedCategory) convertForCategory(row, HierarchedCategory.class); + + try { + if (row !=null && row.get("path") != null ) { + final String parentsASJsonArray = "[" + row.get("path") + "]"; + + final List parentList = ((List>) JsonUtil.getObjectFromJson(parentsASJsonArray, List.class)) + .stream() + .map(map -> new ShortCategory.Builder() + .setCategoryName(map.get("categoryName")) + .setKey(map.get("key")) + .setInode(map.get(INODE)) + .build() + ) + .collect(Collectors.toList()); + + category.setParentList(parentList.subList(0, parentList.size() - 1)); + } + + categories.add(category); + } catch (IOException e) { + Logger.warn(CategoryFactoryImpl.class, e::getMessage); + } + } + } + + return categories; + } + + private Category convertForCategory(final Map sqlResult) { + return convertForCategory(sqlResult, Category.class); + } + /** * Converts the category information coming from the database into a {@link Category} * object with all of its properties. If the information is not present, a @@ -625,15 +669,15 @@ List convertForCategories(final List> sqlResults) * @param sqlResult - The data of a specific category from the database. * @return The {@link Category} object. */ - private Category convertForCategory(final Map sqlResult) { + private Category convertForCategory(final Map sqlResult, Class clazz) { Category category = null; if ( sqlResult != null ) { - category = new Category(); + category = ReflectionUtils.newInstance(clazz); Object sortOrder = sqlResult.get("sort_order"); - category.setInode((String) sqlResult.get("inode")); + category.setInode((String) sqlResult.get(INODE)); category.setCategoryName((String) sqlResult.get("category_name")); category.setKey((String) sqlResult.get("category_key")); if ( sortOrder != null ) { @@ -805,7 +849,7 @@ public void sortChildren(final String inode) throws DotDataException { private void putResultInCatCache( final ResultSet rs ) throws SQLException, DotDataException { while(rs.next()) { // calling find will put it into cache internally - find(rs.getString("inode")); + find(rs.getString(INODE)); } } @@ -841,11 +885,11 @@ protected String suggestVelocityVarName(final String categoryVelVarName) throws * @return * @throws DotDataException */ - public List findAll(final CategorySearchCriteria searchCriteria) + public List findAll(final CategorySearchCriteria searchCriteria) throws DotDataException { - if (!UtilMethods.isSet(searchCriteria.rootInode) && !UtilMethods.isSet(searchCriteria.filter)) { - return findAll(); + if (searchCriteria.rootInode == null) { + throw new IllegalArgumentException(); } final String query = getFindAllSQLQuery(searchCriteria); @@ -862,10 +906,12 @@ public List findAll(final CategorySearchCriteria searchCriteria) dc.addObject("%" + searchCriteria.filter.toLowerCase() + "%"); } - final List categories = convertForCategories(UtilMethods.isSet(searchCriteria.rootInode) ? + final List> results = UtilMethods.isSet(searchCriteria.rootInode) ? dc.loadObjectResults().stream() - .filter(map -> !map.get("inode").equals(searchCriteria.rootInode)) - .collect(Collectors.toList()) : dc.loadObjectResults()); + .filter(map -> !map.get(INODE).equals(searchCriteria.rootInode)) + .collect(Collectors.toList()) : dc.loadObjectResults(); + + final List categories = convertForHierarchedCategories(results); updateCache(categories); return categories; @@ -873,11 +919,13 @@ public List findAll(final CategorySearchCriteria searchCriteria) private static String getFindAllSQLQuery(CategorySearchCriteria searchCriteria) { final String queryTemplate = "WITH RECURSIVE CategoryHierarchy AS ( " + - "SELECT c.* FROM Category c %s " + + "SELECT c.*, json_build_object('inode', inode, 'categoryName', category_name, 'key', category_key)::varchar AS path " + + "FROM Category c %s " + "UNION ALL " + - "SELECT c.* FROM Category c JOIN tree t ON c.inode = t.child JOIN CategoryHierarchy ch ON t.parent = ch.inode " + + "SELECT c.*, CONCAT(ch.path, ',', json_build_object('inode', c.inode, 'categoryName', c.category_name, 'key', c.category_key)::varchar) AS path " + + "FROM Category c JOIN tree t ON c.inode = t.child JOIN CategoryHierarchy ch ON t.parent = ch.inode " + ") " + - "SELECT * FROM CategoryHierarchy %s ORDER BY %s %s"; + "SELECT distinct *,path FROM CategoryHierarchy %s ORDER BY %s %s"; final String rootCategoryFilter = UtilMethods.isSet(searchCriteria.rootInode) ? "WHERE c.inode = ?" : StringPool.BLANK; @@ -886,12 +934,11 @@ private static String getFindAllSQLQuery(CategorySearchCriteria searchCriteria) "LOWER(category_key) LIKE ? OR " + "LOWER(category_velocity_var_name) LIKE ?" : StringPool.BLANK; - final String query = String.format(queryTemplate, rootCategoryFilter, filterCategories, searchCriteria.orderBy, + return String.format(queryTemplate, rootCategoryFilter, filterCategories, searchCriteria.orderBy, searchCriteria.direction.toString()); - return query; } - private void updateCache(List categories) throws DotDataException { + private void updateCache(List categories) throws DotDataException { for(final Category category : categories) { if(catCache.get(category.getInode()) == null) try { diff --git a/dotCMS/src/main/java/com/dotmarketing/portlets/categories/model/Category.java b/dotCMS/src/main/java/com/dotmarketing/portlets/categories/model/Category.java index 31360029a012..7be50e3d7efe 100644 --- a/dotCMS/src/main/java/com/dotmarketing/portlets/categories/model/Category.java +++ b/dotCMS/src/main/java/com/dotmarketing/portlets/categories/model/Category.java @@ -24,6 +24,7 @@ import com.liferay.portal.model.User; import org.apache.commons.lang.builder.ToStringBuilder; +import javax.ws.rs.NotSupportedException; import java.io.Serializable; import java.util.ArrayList; import java.util.Date; @@ -267,5 +268,4 @@ public ManifestInfo getManifestInfo() { .title(this.getCategoryName()) .build(); } - } diff --git a/dotCMS/src/main/java/com/dotmarketing/portlets/categories/model/HierarchedCategory.java b/dotCMS/src/main/java/com/dotmarketing/portlets/categories/model/HierarchedCategory.java new file mode 100644 index 000000000000..dfc9f0525635 --- /dev/null +++ b/dotCMS/src/main/java/com/dotmarketing/portlets/categories/model/HierarchedCategory.java @@ -0,0 +1,44 @@ +package com.dotmarketing.portlets.categories.model; + +import java.util.List; +import java.util.Objects; + +/** + * Represents a {@link Category} with its hierarchy calculated. + * This means traversing from the current category all the way up to the first-level category that you encounter. + * + * For example: + * + * | Name | Parent | hierarchy | + * |-------------|----------------|------------------------ | + * | Top Category| null | [] | + * | Child | Top Category | [Top Category] | + * | Grand Child | Child | [Top Category, Child] | + * + */ +public class HierarchedCategory extends Category{ + + private List parentList; + + public void setParentList(final List parentList) { + this.parentList = parentList; + } + + public List getParentList() { + return parentList; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + HierarchedCategory that = (HierarchedCategory) o; + return Objects.equals(parentList, that.parentList); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), parentList); + } +} diff --git a/dotCMS/src/main/java/com/dotmarketing/portlets/categories/model/ShortCategory.java b/dotCMS/src/main/java/com/dotmarketing/portlets/categories/model/ShortCategory.java new file mode 100644 index 000000000000..f6b146897e88 --- /dev/null +++ b/dotCMS/src/main/java/com/dotmarketing/portlets/categories/model/ShortCategory.java @@ -0,0 +1,60 @@ +package com.dotmarketing.portlets.categories.model; + +import java.io.Serializable; + +/** + * Represents a {@link Category}, but only contains the most important data: + * + * - Category's name + * - Category's key + * - Category's inode + */ +public class ShortCategory implements Serializable { + + private String categoryName; + private String inode; + private String key; + + private ShortCategory(final Builder builder) { + this.categoryName = builder.categoryName; + this.inode = builder.inode; + this.key = builder.key; + } + + public String getCategoryName() { + return categoryName; + } + + public String getInode() { + return inode; + } + + public String getKey() { + return key; + } + + public static class Builder { + private String categoryName; + private String inode; + private String key; + + public Builder setCategoryName(String categoryName) { + this.categoryName = categoryName; + return this; + } + + public Builder setInode(String inode) { + this.inode = inode; + return this; + } + + public Builder setKey(String key) { + this.key = key; + return this; + } + + public ShortCategory build() { + return new ShortCategory(this); + } + } +} diff --git a/dotcms-integration/src/test/java/com/dotmarketing/portlets/categories/business/CategoryAPITest.java b/dotcms-integration/src/test/java/com/dotmarketing/portlets/categories/business/CategoryAPITest.java index 5898d24dbb42..8df95b568119 100644 --- a/dotcms-integration/src/test/java/com/dotmarketing/portlets/categories/business/CategoryAPITest.java +++ b/dotcms-integration/src/test/java/com/dotmarketing/portlets/categories/business/CategoryAPITest.java @@ -34,6 +34,7 @@ import com.dotmarketing.exception.DotDataException; import com.dotmarketing.exception.DotSecurityException; import com.dotmarketing.portlets.categories.model.Category; +import com.dotmarketing.portlets.categories.model.HierarchedCategory; import com.dotmarketing.portlets.contentlet.business.ContentletAPI; import com.dotmarketing.portlets.contentlet.business.HostAPI; import com.dotmarketing.portlets.contentlet.model.Contentlet; @@ -1545,7 +1546,7 @@ public void test_save_createTopLevelCategory_asLimitedUser_fail() } /** - * Method to test: {@link CategoryAPIImpl#findAll(CategoryFactory.CategorySearchCriteria, User, boolean)} + * Method to test: {@link CategoryAPIImpl#findAll(CategorySearchCriteria, User, boolean)} * When: Call the API method * Should: it should * - Use the {@link CategoryFactoryImpl#findAll(CategorySearchCriteria)} to search the {@link Category} @@ -1567,12 +1568,12 @@ public void getAllCategoriesFiltered() throws DotDataException, DotSecurityExcep final User user = mock(); - final Category category1 = mock(Category.class); - final Category category2 = mock(Category.class); - final Category category3 = mock(Category.class); + final HierarchedCategory category1 = mock(HierarchedCategory.class); + final HierarchedCategory category2 = mock(HierarchedCategory.class); + final HierarchedCategory category3 = mock(HierarchedCategory.class); - final List categoriesAfterSearch = list(category1, category2, category3); - final List categoriesAfterPermission = list(category1, category2); + final List categoriesAfterSearch = list(category1, category2, category3); + final List categoriesAfterPermission = list(category1, category2); final CategoryFactory categoryFactory = mock(); when(categoryFactory.findAll(searchingCriteria)).thenReturn(categoriesAfterSearch); @@ -1621,19 +1622,19 @@ public void getAllCategoriesFilteredWithPagination() throws DotDataException, Do .offset(5) .build(); - final Category category1 = mock(Category.class); - final Category category2 = mock(Category.class); - final Category category3 = mock(Category.class); - final Category category4 = mock(Category.class); - final Category category5 = mock(Category.class); - final Category category6 = mock(Category.class); - final Category category7 = mock(Category.class); - final Category category8 = mock(Category.class); - final Category category9 = mock(Category.class); + final HierarchedCategory category1 = mock(HierarchedCategory.class); + final HierarchedCategory category2 = mock(HierarchedCategory.class); + final HierarchedCategory category3 = mock(HierarchedCategory.class); + final HierarchedCategory category4 = mock(HierarchedCategory.class); + final HierarchedCategory category5 = mock(HierarchedCategory.class); + final HierarchedCategory category6 = mock(HierarchedCategory.class); + final HierarchedCategory category7 = mock(HierarchedCategory.class); + final HierarchedCategory category8 = mock(HierarchedCategory.class); + final HierarchedCategory category9 = mock(HierarchedCategory.class); final User user = mock(); - final List categories = list(category1, category2, category3, category4, category5, category6, + final List categories = list(category1, category2, category3, category4, category5, category6, category7, category8, category9); final CategoryFactory categoryFactory = mock(); diff --git a/dotcms-integration/src/test/java/com/dotmarketing/portlets/categories/business/CategoryFactoryTest.java b/dotcms-integration/src/test/java/com/dotmarketing/portlets/categories/business/CategoryFactoryTest.java index 70de9fbd6083..a6c0903f41d0 100644 --- a/dotcms-integration/src/test/java/com/dotmarketing/portlets/categories/business/CategoryFactoryTest.java +++ b/dotcms-integration/src/test/java/com/dotmarketing/portlets/categories/business/CategoryFactoryTest.java @@ -27,6 +27,8 @@ import java.util.function.Function; import java.util.stream.Collectors; +import com.dotmarketing.portlets.categories.model.HierarchedCategory; +import com.dotmarketing.portlets.categories.model.ShortCategory; import com.liferay.util.StringUtil; import com.tngtech.java.junit.dataprovider.DataProvider; import com.tngtech.java.junit.dataprovider.DataProviderRunner; @@ -313,7 +315,7 @@ public static Object[] findCategoriesFilters() { } /** - * Method to test: {@link CategoryFactoryImpl#findAll(CategoryFactory.CategorySearchCriteria)} + * Method to test: {@link CategoryFactoryImpl#findAll(CategorySearchCriteria)} * When: * * - Create a random string to be used as the filter for the test. @@ -417,43 +419,35 @@ public void getAllCategoriesFiltered(final FilterTestCase filterTestCase) throws /** * Method to test: {@link CategoryFactoryImpl#findAll(CategorySearchCriteria)} - * When: call the method with filter and inode equals to null - * Should: return all the Categories + * When: Create root inode is null and filter is not null + * Should: throw a {@link IllegalArgumentException} * * @throws DotDataException */ - @Test - public void getAllCategoriesWithNullFilterAndInode() throws DotDataException { - final Category topLevelCategory_1 = new CategoryDataGen().setCategoryName("Top Level Category") - .setKey("top_level_categoria") - .setCategoryVelocityVarName("top_level_categoria") - .nextPersisted(); + @Test(expected = IllegalArgumentException.class) + public void getAllCategoriesWithNullInode() throws DotDataException { - final Category childCategory_1 = new CategoryDataGen().setCategoryName("Child Category 1") - .setKey("child_category_1") - .setCategoryVelocityVarName("child_category_1") - .parent(topLevelCategory_1) - .nextPersisted(); + final CategorySearchCriteria categorySearchCriteria = new CategorySearchCriteria.Builder() + .filter("testing") + .build(); - final Category childCategory_2 = new CategoryDataGen().setCategoryName("Child Category 2") - .setKey("child_category_2") - .setCategoryVelocityVarName("child_category_2") - .parent(topLevelCategory_1) - .nextPersisted(); + FactoryLocator.getCategoryFactory().findAll(categorySearchCriteria); - final Category grandchildCategory_1 = new CategoryDataGen().setCategoryName("Grand Child Category 1") - .setKey("grand_child_category_1") - .setCategoryVelocityVarName("grand_child_category_1") - .parent(childCategory_2) - .nextPersisted(); + } - final CategorySearchCriteria categorySearchCriteria = new CategorySearchCriteria.Builder() - .build(); + /** + * Method to test: {@link CategoryFactoryImpl#findAll(CategorySearchCriteria)} + * When: Called the method with filter and inode set to null + * Should: throw a {@link IllegalArgumentException} + * + * @throws DotDataException + */ + @Test(expected = IllegalArgumentException.class) + public void getAllCategoriesWithNullFilterAndInode() throws DotDataException { - final Collection categoriesWithFilter = FactoryLocator.getCategoryFactory().findAll(categorySearchCriteria); - final List categoriesWithoutFilter = FactoryLocator.getCategoryFactory().findAll(); + final CategorySearchCriteria categorySearchCriteria = new CategorySearchCriteria.Builder().build(); - assertTrue(Objects.deepEquals(categoriesWithoutFilter, categoriesWithFilter)); + FactoryLocator.getCategoryFactory().findAll(categorySearchCriteria); } /** @@ -582,6 +576,57 @@ public void getAllCategoriesFilteredOrdered() throws DotDataException { } + @Test + public void hierarchyCategory() throws DotDataException { + final Category topLevelCategory = new CategoryDataGen().setCategoryName("Top Level Category") + .setKey("top_level") + .setCategoryVelocityVarName("top_level_categoria") + .nextPersisted(); + + final Category childCategory = new CategoryDataGen().setCategoryName("Child Category") + .setKey("child") + .setCategoryVelocityVarName("child_category") + .parent(topLevelCategory) + .nextPersisted(); + + final Category grandChildCategory = new CategoryDataGen().setCategoryName("Grand Child Category") + .setKey("grand_child") + .setCategoryVelocityVarName("grand_child_category") + .parent(childCategory) + .nextPersisted(); + + final Category greatGrandchildCategory = new CategoryDataGen().setCategoryName("Great Grand Child Category") + .setKey("great_grand_child") + .setCategoryVelocityVarName("great_grand_child_category") + .parent(grandChildCategory) + .nextPersisted(); + + final CategorySearchCriteria categorySearchCriteria = new CategorySearchCriteria.Builder() + .rootInode(topLevelCategory.getInode()) + .filter("Great Grand Child") + .build(); + + final List categories = FactoryLocator.getCategoryFactory().findAll(categorySearchCriteria); + + assertEquals(1, categories.size()); + assertEquals(greatGrandchildCategory.getInode(), categories.get(0).getInode()); + + final List hierarchy = categories.get(0).getParentList(); + assertEquals(3, hierarchy.size()); + + assertEquals(hierarchy.get(0).getCategoryName(), topLevelCategory.getCategoryName()); + assertEquals(hierarchy.get(0).getKey(), topLevelCategory.getKey()); + assertEquals(hierarchy.get(0).getInode(), topLevelCategory.getInode()); + + assertEquals(hierarchy.get(1).getCategoryName(), childCategory.getCategoryName()); + assertEquals(hierarchy.get(1).getKey(), childCategory.getKey()); + assertEquals(hierarchy.get(1).getInode(), childCategory.getInode()); + + assertEquals(hierarchy.get(2).getCategoryName(), grandChildCategory.getCategoryName()); + assertEquals(hierarchy.get(2).getKey(), grandChildCategory.getKey()); + assertEquals(hierarchy.get(2).getInode(), grandChildCategory.getInode()); + } + private static class FilterTestCase { private String filter; private Function transformToSearch; diff --git a/dotcms-postman/src/main/resources/postman/Category.postman_collection.json b/dotcms-postman/src/main/resources/postman/Category.postman_collection.json index 3bdd253c5448..1b9b85825f59 100644 --- a/dotcms-postman/src/main/resources/postman/Category.postman_collection.json +++ b/dotcms-postman/src/main/resources/postman/Category.postman_collection.json @@ -1,6 +1,6 @@ { "info": { - "_postman_id": "6101d86a-acc3-42d5-a3cb-266d9c1e7a72", + "_postman_id": "d13b8154-b0c4-46eb-afcd-902105508f76", "name": "Category", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", "_exporter_id": "30436704" @@ -2847,7 +2847,22 @@ "", " for (let i = 0; i < jsonData.entity.length; i++)", " { ", - " data.push(jsonData.entity[i]['categoryName']); ", + " data.push(jsonData.entity[i]['categoryName']); ", + "", + " if (i === 0) {", + " pm.expect('PostmanTest Child 1').to.have.equals(jsonData.entity[i].categoryName);", + " pm.expect(1).to.have.equals(jsonData.entity[i].parentList.length);", + " pm.expect('PostmanTest Top level Category').to.have.equals(jsonData.entity[i].parentList[0].categoryName);", + " } else if (i === 1) {", + " pm.expect('PostmanTest Child 2').to.have.equals(jsonData.entity[i].categoryName);", + " pm.expect(1).to.have.equals(jsonData.entity[i].parentList.length);", + " pm.expect('PostmanTest Top level Category').to.have.equals(jsonData.entity[i].parentList[0].categoryName);", + " } else if (i === 2) {", + " pm.expect('PostmanTest Grandchild 1').to.have.equals(jsonData.entity[i].categoryName);", + " pm.expect(2).to.have.equals(jsonData.entity[i].parentList.length);", + " pm.expect('PostmanTest Top level Category').to.have.equals(jsonData.entity[i].parentList[0].categoryName);", + " pm.expect('Child 3').to.have.equals(jsonData.entity[i].parentList[1].categoryName);", + " } ", " }", "", " data.includes(\"PostmanTest Child 1\");",