Skip to content

Commit

Permalink
#28896 Creating API Level class to search Categories on the entire tree
Browse files Browse the repository at this point in the history
  • Loading branch information
freddyDOTCMS committed Jul 2, 2024
1 parent 7e09771 commit 476f287
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -484,4 +484,17 @@ Category findByVariable(final String variable, final User user,
final boolean respectFrontendRoles) throws DotDataException, DotSecurityException;

List<Category> getCategoriesFromContent(final Contentlet contentlet, final User user, boolean respectFrontendRoles ) throws DotDataException, DotSecurityException;

/**
* Return a list of Categories regardless of their levels.
*
* @param searchCriteria Searching criteria
* @param user User to check Permission
* @param respectFrontendRoles true if you must respect Frontend Roles
*
* @return List of Category filtered
*/
PaginatedCategories findAll(final CategoryFactory.CategorySearchCriteria searchCriteria,
final User user, boolean respectFrontendRoles)
throws DotDataException, DotSecurityException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.dotmarketing.util.InodeUtils;
import com.dotmarketing.util.Logger;
import com.dotmarketing.util.UtilMethods;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.liferay.portal.model.User;
import java.util.ArrayList;
Expand All @@ -48,8 +49,13 @@ public class CategoryAPIImpl implements CategoryAPI {
private final PermissionAPI permissionAPI;

public CategoryAPIImpl () {
categoryFactory = FactoryLocator.getCategoryFactory();
permissionAPI = APILocator.getPermissionAPI();
this(FactoryLocator.getCategoryFactory(), APILocator.getPermissionAPI());
}

@VisibleForTesting
public CategoryAPIImpl (final CategoryFactory categoryFactory, final PermissionAPI permissionAPI) {
this.categoryFactory = categoryFactory;
this.permissionAPI = permissionAPI;
}

/**
Expand Down Expand Up @@ -943,4 +949,31 @@ private boolean hasCategoryFields(final ContentType contentType) {

}

/**
* Default implementation.
*
* @param searchCriteria Searching criteria
* @param user User to check Permission
* @param respectFrontendRoles true if you must respect Frontend Roles
*
* @return
* @throws DotDataException
* @throws DotSecurityException
*/
@CloseDBIfOpened
@Override
public PaginatedCategories findAll(final CategoryFactory.CategorySearchCriteria searchCriteria,
final User user, boolean respectFrontendRoles)
throws DotDataException, DotSecurityException {

if (searchCriteria.limit < 1) {
throw new IllegalArgumentException("Limit must be greater than 0");
}

final List<Category> categories = permissionAPI.filterCollection(categoryFactory.findAll(searchCriteria),
PermissionAPI.PERMISSION_READ, respectFrontendRoles, user);

return getCategoriesSubList(searchCriteria.offset, searchCriteria.limit, categories, null);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ public abstract class CategoryFactory {
*
* @return List of Category filtered
*/
public abstract Collection<Category> findAll(final CategorySearchCriteria searchCriteria) throws DotDataException;
public abstract List<Category> findAll(final CategorySearchCriteria searchCriteria) throws DotDataException;

/**
* Represents Search Criteria for {@link Category} searching, you cans set the follow:
Expand All @@ -304,19 +304,24 @@ public static class CategorySearchCriteria {
final String filter;
final String orderBy;
final OrderDirection direction;

final int limit;
final int offset;
private CategorySearchCriteria (final Builder builder) {
this.rootInode = builder.rootInode;
this.filter = builder.filter;
this.orderBy = builder.orderBy;
this.direction = builder.direction;
this.limit = builder.limit;
this.offset = builder.offset;
}

public static class Builder {
private String rootInode;
private String filter;
private String orderBy = "category_name";
private OrderDirection direction = OrderDirection.ASC;
private int limit = -1;
private int offset = 0;

public Builder rootInode(String rootInode) {
this.rootInode = rootInode;
Expand All @@ -338,6 +343,17 @@ public Builder direction(OrderDirection direction) {
return this;
}

public Builder limit(int limit) {
this.limit = limit;
return this;
}

public Builder offset(int offset) {
this.offset = offset;
return this;
}


public CategorySearchCriteria build() {
return new CategorySearchCriteria(this);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package com.dotmarketing.portlets.categories.business;

import static com.dotcms.util.CollectionsUtils.list;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import com.dotcms.IntegrationTestBase;
import com.dotcms.contenttype.business.ContentTypeAPIImpl;
Expand All @@ -21,6 +24,7 @@
import com.dotcms.datagen.SiteDataGen;
import com.dotcms.datagen.UserDataGen;
import com.dotcms.util.IntegrationTestInitService;
import com.dotcms.util.pagination.OrderDirection;
import com.dotmarketing.beans.Host;
import com.dotmarketing.beans.Permission;
import com.dotmarketing.business.APILocator;
Expand All @@ -45,6 +49,8 @@
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import net.bytebuddy.utility.RandomString;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
Expand Down Expand Up @@ -91,7 +97,7 @@ public void findTopLevelCategories() throws DotSecurityException, DotDataExcepti
int count = 10;//TODO: A -1 or 0 wont work in order to request all que records
String filter = null;
String sort = null;

//Test the category API
PaginatedCategories categories = categoryAPI.findTopLevelCategories(user, false, start, count, filter, sort);

Expand Down Expand Up @@ -1537,4 +1543,123 @@ public void test_save_createTopLevelCategory_asLimitedUser_fail()

categoryAPI.save(null, newCategory, limitedUser, false);
}

/**
* Method to test: {@link CategoryAPIImpl#findAll(CategoryFactory.CategorySearchCriteria, User, boolean)}
* When: Call the API method
* Should: it should
* - Use the {@link CategoryFactoryImpl#findAll(CategoryFactory.CategorySearchCriteria)} to search the {@link Category}
* - Use the {@link PermissionAPI#filterCollection(List, int, boolean, User)} method to check permission
*/
@Test
public void getAllCategoriesFiltered() throws DotDataException, DotSecurityException {
final String inode = new RandomString().nextString();
final String filter = new RandomString().nextString();
final String orderBy = "category_key";

final CategoryFactory.CategorySearchCriteria searchingCriteria =
new CategoryFactory.CategorySearchCriteria.Builder()
.rootInode(inode)
.direction(OrderDirection.DESC)
.orderBy(orderBy)
.filter(filter)
.limit(10)
.build();

final User user = mock();

final Category category1 = mock(Category.class);
final Category category2 = mock(Category.class);
final Category category3 = mock(Category.class);

final List<Category> categoriesAfterSearch = list(category1, category2, category3);
final List<Category> categoriesAfterPermission = list(category1, category2);

final CategoryFactory categoryFactory = mock();
when(categoryFactory.findAll(searchingCriteria)).thenReturn(categoriesAfterSearch);

final PermissionAPI permissionAPI = mock();
when(permissionAPI.filterCollection(categoriesAfterSearch, PermissionAPI.PERMISSION_READ, false, user))
.thenReturn(categoriesAfterPermission);

final CategoryAPI categoryAPI = new CategoryAPIImpl(categoryFactory, permissionAPI);
PaginatedCategories paginatedCategories = categoryAPI.findAll(searchingCriteria, user, false);

assertEquals(categoriesAfterPermission.size(), (int) paginatedCategories.getTotalCount());
assertTrue(categoriesAfterPermission.containsAll(paginatedCategories.getCategories()));
}

/**
* Method to test: {@link CategoryAPIImpl#findAll(CategoryFactory.CategorySearchCriteria, User, boolean)}
* When: Create 9 Category, call the two times:
* first: limit =5, offset =0
* second: limit =5, offset =5
*
* Should: Return All the Categories with the 2 called
*/
@Test
public void getAllCategoriesFilteredWithPagination() throws DotDataException, DotSecurityException {
final String inode = new RandomString().nextString();
final String filter = new RandomString().nextString();
final String orderBy = "category_key";

final CategoryFactory.CategorySearchCriteria searchingCriteria_1 =
new CategoryFactory.CategorySearchCriteria.Builder()
.rootInode(inode)
.direction(OrderDirection.DESC)
.orderBy(orderBy)
.filter(filter)
.limit(5)
.offset(0)
.build();

final CategoryFactory.CategorySearchCriteria searchingCriteria_2 =
new CategoryFactory.CategorySearchCriteria.Builder()
.rootInode(inode)
.direction(OrderDirection.DESC)
.orderBy(orderBy)
.filter(filter)
.limit(5)
.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 User user = mock();

final List<Category> categories = list(category1, category2, category3, category4, category5, category6,
category7, category8, category9);

final CategoryFactory categoryFactory = mock();
when(categoryFactory.findAll(searchingCriteria_1)).thenReturn(categories);
when(categoryFactory.findAll(searchingCriteria_2)).thenReturn(categories);

final PermissionAPI permissionAPI = mock();
when(permissionAPI.filterCollection(categories, PermissionAPI.PERMISSION_READ, false, user))
.thenReturn(categories);



final CategoryAPI categoryAPI = new CategoryAPIImpl(categoryFactory, permissionAPI);
PaginatedCategories firstPage = categoryAPI.findAll(searchingCriteria_1, user, false);

assertEquals(9, (int) firstPage.getTotalCount());
assertEquals(5, firstPage.getCategories().size());
assertTrue(list(category1, category2, category3, category4, category5).containsAll(firstPage.getCategories()));


PaginatedCategories secondPage = categoryAPI.findAll(searchingCriteria_2, user, false);

assertEquals(9, (int) secondPage.getTotalCount());
assertEquals(4, secondPage.getCategories().size());
assertTrue(list(category6, category7, category8, category9).containsAll(secondPage.getCategories()));
}
}

0 comments on commit 476f287

Please sign in to comment.